I am getting strange behavior from a spec/ factory. What am I doing wrong?
# 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>
The test is failing:
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
I thought it odd that user1 was passing whereas user 2 was failing, so I got rspec to save_and_open_page
.
<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>
Exactly the same code and factory is used for each user, so:
Am I using FactoryGirl incorrectly? I can't work out what I'm doing wrong, and any advice appreciated.
The reason FactoryGirl is creating all users with the same name is because the name value is being set when your factory is defined. To get around this you should use lazy attributes: https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#lazy-attributes
to do this use parenthesis in your name trait as follows:
trait :name do
name { Faker::Name.name }
end
this will mean that a new name is generated each time a new instance is created.
Unfortunately I can't see exactly what the problem is with your avatar. One thing you could try is fixture_file_upload and see if that helps.
To use this you need to add include ActionDispatch::TestProcess
in your spec helper. Then try changing your avatar trait to:
trait :avatar do
avatar { fixture_file_upload(Rails.root.join('spec', 'support', 'images', 'test_image.jpg'), 'image/jpg') }
end
I hope that helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.