使用Let构建模型的多个实例

时间:2017-05-11 01:49:23

标签: ruby-on-rails ruby rspec capybara factory-bot

我试图在will_paginate上运行测试。我知道它在技术上有效,但由于我无法创建多个记录,因此无法使规范生效。我在Ruby on Rails上使用Capybara和Rspec。

以下是我的功能规范中的内容。

RSpec.describe "Users Index", type: :feature do
 describe "Pagination" do 
  let(:valid_user) { create(:user, name: "Mogli") }
  let(:other_user) { create(:user, 50) }

   it "successfully paginates" do
    log_in_as_feature(valid_user)
    visit users_path
    puts URI.parse(current_url)
    expect(page).to have_css('div.pagination')
    expect(page).to have_link(href: user_path(valid_user), text: valid_user.name)
    first_page_of_users = User.paginate(page: 1)
    first_page_of_users.each do |user|
      expect(page).to have_link(href: user_path(user), text: user.name)
      unless user == valid_user
        expect(page).to have_link(href: user_path(user), text: "delete")
      end
    end
  end
end

我的工厂很简单:

FactoryGirl.define do
 sequence(:name) { |n| "Person#{n}" }

  factory :user do
   name
   email { "#{name}@example.com" }
   password "foobar"
   password_confirmation "foobar"
   activated true
   activated_at Time.zone.now
  end
end

我的第四行是罪魁祸首。它实际上并没有构建用户。我尝试使用FactoryGirl.create(:user, 50),但最终会全面打破27个测试,我必须重置测试数据库。

我不知道如何同时创建多个虚拟用户,同时保持Mogli为第一。任何见解都表示赞赏。

编辑:如果我评论了has_css测试,那么我的测试通过了。

这是div的错误

1) Users Index Pagination successfully paginates Failure/Error: expect(page).to have_css('div.pagination') expected to find css "div.pagination" but there were no matches # ./spec/features/users_index_spec.rb:13:in阻止(3级)'

以0.82368秒结束(加载文件需要2.17秒)`

编辑:添加我的partial和index.html.erb视图。

我的观点只是呈现@users partial

是:

1 <li>
2   <%= gravatar_for user, size: 50 %>
3   <%= link_to user.name, user %>
4   <% if current_user.admin? && !current_user?(user) %>
5     | <%= link_to "delete", user, method: :delete,
6                                   data: { confirm: "You sure?" } %>
7   <% end %>
8
9 </li>

3 个答案:

答案 0 :(得分:2)

首先,letlazy-evaluated。这意味着在您在规范中调用它之前,它不会被评估。您没有在规范中使用other_user,因此不会对其进行评估。

其次,如果您要创建一个包含50个用户的列表来设置规范,请使用before块:

before do
  # using create_list
  create_list(:user, 50)

  # OR just
  50.times { create(:user) }
end

it "successfully paginates" do
  # ...
end

答案 1 :(得分:2)

您的示例有一些问题。正如其他人所提到的let被懒惰地评估,因此要创建不直接引用的对象,您需要使用let!。此外,FactoryGirl的create并未生成大量记录,您需要create_list。最后,Capybara的have_link会将您正在寻找的链接文字作为第一个参数,因此无需传递:text选项

RSpec.describe "Users Index", type: :feature do
 describe "Pagination" do 
  let!(:valid_user) { create(:user, name: "Mogli") }
  let!(:other_users) { create_list(:user, 50) }

   it "successfully paginates" do
    log_in_as_feature(valid_user)
    visit users_path
    puts URI.parse(current_url)
    expect(page).to have_css('div.pagination')
    expect(page).to have_link(valid_user.name, href: user_path(valid_user))
    User.paginate(page: 1).each do |user|
      expect(page).to have_link(user.name, href: user_path(user))
      expect(page).to have_link("delete", href: user_path(user)) unless user == valid_user
    end
  end
end

答案 2 :(得分:1)

如Jan所述,let被懒惰评估。如果您不使用other_user,则永远不会创建它。但是,他们是一个热切的对手。

let!(:other_user) { create(:user, 50) }

总是创建这个。