Rails Minitest 集成测试损坏:预计至少有 1 个元素匹配 "div.pagination",找到 0 个

Rails Minitest integration test broken: Expected at least 1 element matching "div.pagination", found 0

我们正在使用 Michael Hartl 的 Rails 教程作为灵感来构建完全不同的 RoR 应用程序。

但是,我们偶然发现了一个问题,该问题可能对学习本教程的其他人有所帮助。

这是我们的 user_index_test.rb 文件:

test "index as admin including pagination and delete links" do
    log_in_as(@admin)
    get users_path
    assert_select 'div.pagination'
    first_page_of_users = User.paginate(page: 1)
    first_page_of_users.each do |user|
      assert_select 'a[href=?]', user_path(user), text: user.first_name + " " + user.first_name
      unless user == @admin
        assert_select 'a[href=?]', user_path(user), text: 'delete'
      end
    end
    assert_difference 'User.count', -1 do
      delete user_path(@non_admin)
    end
  end

这是我们的 index.html.erb 文件:

<h1>All users</h1>

<div class="row">

    <div class="pagination col-md-6 col-md-offset-3">

        <%= will_paginate %>

        <ul class="users">
          <% @users.each do |user| %>
            <%= render user %>
          <% end %>
        </ul>

        <%= will_paginate %>

    </div>

</div>

在浏览器中呈现以下 HTML:

<div class="row">

    <div class="col-md-6 col-md-offset-3">

        <div class="pagination"><ul class="pagination"><li class="prev previous_page disabled"><a href="#">← Previous</a></li> <li class="active"><a rel="start" href="/users?page=1">1</a></li> <li><a rel="next" href="/users?page=2">2</a></li> <li><a href="/users?page=3">3</a></li> <li><a href="/users?page=4">4</a></li> <li><a href="/users?page=5">5</a></li> <li><a href="/users?page=6">6</a></li> <li><a href="/users?page=7">7</a></li> <li><a href="/users?page=8">8</a></li> <li><a href="/users?page=9">9</a></li> <li><a href="/users?page=10">10</a></li> <li><a href="/users?page=11">11</a></li> <li class="next next_page "><a rel="next" href="/users?page=2">Next →</a></li></ul></div>

        <ul class="users">
            <li>
  <a href="/users/1">Billy Joel</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/1">delete</a>
</li>
            <li>
  <a href="/users/2">Stevie Wonder</a>
</li>
            <li>
  <a href="/users/3">Michael Jackson</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/3">delete</a>
</li>
            <li>
  <a href="/users/4">Sterling Archer</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/4">delete</a>
</li>
            <li>
  <a href="/users/5">Telly Miller</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/5">delete</a>
</li>
            <li>
  <a href="/users/6">Elvie Lindgren</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/6">delete</a>
</li>
            <li>
  <a href="/users/7">Kianna Beier</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/7">delete</a>
</li>
            <li>
  <a href="/users/8">Wilhelmine Wuckert</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/8">delete</a>
</li>
            <li>
  <a href="/users/9">Blanche Moore</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/9">delete</a>
</li>
            <li>
  <a href="/users/10">Hailey Jacobson</a>
    | <a data-confirm="You sure?" rel="nofollow" data-method="delete" href="/users/10">delete</a>
</li>
        </ul>

        <div class="pagination"><ul class="pagination"><li class="prev previous_page disabled"><a href="#">← Previous</a></li> <li class="active"><a rel="start" href="/users?page=1">1</a></li> <li><a rel="next" href="/users?page=2">2</a></li> <li><a href="/users?page=3">3</a></li> <li><a href="/users?page=4">4</a></li> <li><a href="/users?page=5">5</a></li> <li><a href="/users?page=6">6</a></li> <li><a href="/users?page=7">7</a></li> <li><a href="/users?page=8">8</a></li> <li><a href="/users?page=9">9</a></li> <li><a href="/users?page=10">10</a></li> <li><a href="/users?page=11">11</a></li> <li class="next next_page "><a rel="next" href="/users?page=2">Next →</a></li></ul></div>

    </div>

</div>

然而,这是集成测试的结果:

FAIL["test_index_as_admin_including_pagination_and_delete_links", UsersIndexTest, 2015-06-30 06:44:20 -0700]
 test_index_as_admin_including_pagination_and_delete_links#UsersIndexTest (1435671860.33s)
        Expected at least 1 element matching "div.pagination", found 0..
        Expected 0 to be >= 1.
        test/integration/users_index_test.rb:23:in `block in <class:UsersIndexTest>'

知道哪里出了问题吗?

更新:根据@steve klein 的建议(来自评论),我们更新了 users_index_test.rb 文件:

test "index as admin including pagination and delete links" do
    log_in_as(@admin)
    get users_path
    assert_template 'users/index'
    assert_select 'div.pagination'
    first_page_of_users = User.paginate(page: 1)
    first_page_of_users.each do |user|
      assert_select 'a[href=?]', user_path(user), text: user.first_name + " " + user.first_name
      unless user == @admin
        assert_select 'a[href=?]', user_path(user), text: 'delete'
      end
    end
    assert_difference 'User.count', -1 do
      delete user_path(@non_admin)
    end
  end

这是失败的测试结果:

FAIL["test_index_as_admin_including_pagination_and_delete_links", UsersIndexTest, 2015-06-30 06:44:19 -0700]
 test_index_as_admin_including_pagination_and_delete_links#UsersIndexTest (1435671859.86s)
        expecting <"users/index"> but rendering with <[]>
        test/integration/users_index_test.rb:23:in `block in <class:UsersIndexTest>'

我也收到了这条失败的测试消息,发现我犯了一个有趣的错误:我忘记在 ../test/fixtures/microposts.yml 中将假用户名 "michael" 更改为我自己的测试名。

所以我没有生成足够多的假微博

如果你像我一样经常改变量名,请检查你是否生成了足够的微博来测试。确保 user_index_test.rb@admin 的值等于 microposts.yml 中的 user: your_admin_user_name

希望对您有所帮助 =)

这似乎是 Hartl 教程的问题——这是我发现的第一个错字。我刚刚在学习 Hartl 的教程(第 3 版)时遇到了这个问题。这是我修复它的方法。

我认为问题在于 users_index_test.rb,当它首次在清单 9.44 中引入时,

  @user = users(:michael)

setup方法中。但是下一次我们在清单 9.57 中看到更新的文件时,setup 方法变成了两行:

  @admin     = users(:michael)
  @non_admin = users(:archer)

注意到有什么变化了吗?之前是 @user,现在是 @admin。令人恼火的是,哈特尔并没有像往常一样强调这些台词的不同之处。在这种情况下,您只需要注意差异即可。

所以基本上,无论您使用 @user 还是 @admin,只需确保在导致错误的行中使用相同的变量,即

  unless user == @admin
    assert_select 'a[href=?]', user_path(user), text: 'delete',
                                                method: :delete
  end

如果您完全按照 Hartl 在清单 9.57 中输入的代码输入 @admin,您将不会收到错误。或者您可以将 unless 块中的变量更改为 @user(如果这是您在 setup 方法中的变量),这也会使它起作用。