如何使用FactoryGirl创建多个记录?目前,图像仅应用于第一条记录

时间:2016-03-13 10:14:47

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

我从规格/工厂得到奇怪的行为。我做错了什么?

# feature spec 

feature 'avatars' do
  let(:user1) { create :user_with_profile, role: 1 }
  let(:user2) { create :user_with_profile, role: 2 }
  let(:user3) { create :user_with_profile, role: 3 }
  let(:user4) { create :user_with_profile, role: 4 } 

  scenario 'displays user avatars' do 
    expect(find("ul.users")).to_not have_selector "img.role1[title='#{user1.name}']"
    expect(find("ul.users")).to_not have_selector "img.role2[title='#{user2.name}']"
    expect(find("ul.users")).to_not have_selector "img.role3[title='#{user3.name}']"
    expect(find("ul.users")).to_not have_selector "img.role4[title='#{user4.name}']"
  end
end

# factory

FactoryGirl.define do
  factory :user do
    email { Faker::Internet.email }
    password Faker::Internet.password(10, 20)
    trait :name do
      name Faker::Name.name
    end
    # images are handled with Carrierwave
    trait :avatar do
      avatar { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec', 'support', 'images', 'test_image.jpg')) }
    end
    factory :user_with_profile, traits: [:name, :avatar]
  end
end 

# view
<ul class='users'>
  <% Users.all.each do |user| %>
    <%= content_tag :li, class: "user_#{user.id}" do %>
      <%= link_to user_path(user), title: user.name do %>
        <% if user.avatar? %>
          <%= image_tag user.avatar_url(:large), title: user.name, class: "role#{user.role}" %>
        <% else %>
          <%= content_tag :div, class: "role#{user.role}" do %>
            <%= user.initials %>
          <% end %>
        <% end %>
      <% end %>
    <% end %>
  <% end %>
</ul>

测试失败:

Failure/Error: expect(find("ul.users")).to have_selector "img.role2[title='#{user2.name}']"
expected to find css "img.role2[title='Jakob John']" but there were no matches

我觉得很奇怪user1正在传递而用户2失败了,所以我得到了save_and_open_page的rspec。

<ul class="users">
  <li class="user_1">
    <a title="Jakob Johnson" href="/users/1">
      <img title="Jakob Johnson" class= 'role1' src="/avatars/users/1/large/0000000005_35594307d1.jpg">
    </a>
  </li>
  <li class="user_2">
    <a title="Jakob Johnson" href="/users/2">
      <div class='role2'>JJ</div>
    </a>
  </li>
  ## user3 and user4 also have divs not imgs
</ul>

每个用户都使用完全相同的代码和工厂,因此:

  1. 为什么FactoryGirl使用头像创建user1,而其他用户没有?
  2. 为什么FactoryGirl创建了所有具有相同名称的用户?
  3. 我是否错误地使用FactoryGirl?我无法弄清楚我做错了什么,以及任何建议表示赞赏。

1 个答案:

答案 0 :(得分:2)

FactoryGirl创建具有相同名称的所有用户的原因是因为在定义工厂时正在设置名称值。要解决这个问题,您应该使用延迟属性:https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#lazy-attributes

要执行此操作,请在您的名称特征中使用括号,如下所示:

trait :name do
  name { Faker::Name.name }
end

这意味着每次创建新实例时都会生成一个新名称。

不幸的是,我无法确切地看到您的头像存在什么问题。您可以尝试的一件事是fixture_file_upload,看看是否有帮助。

要使用此功能,您需要在规范助手中添加include ActionDispatch::TestProcess。然后尝试将您的头像特征更改为:

trait :avatar do
  avatar { fixture_file_upload(Rails.root.join('spec', 'support', 'images', 'test_image.jpg'), 'image/jpg') }
end

我希望有所帮助。