Reputation: 124
I am using Factory Girl and Faker to create unique test Users. User model has a uniqueness validation on email.
If I nest 2 levels of describe blocks, then some tests will fail because there are duplicate emails. If I don't nest describe blocks, then all the factory calls return unique Users and the tests pass.
Why does Faker generate duplicate emails in the first scenario?
#factories/user.rb
# a simple factory with Faker
FactoryGirl.define do
factory :student, class: User do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
password { Faker::Lorem.words(3).join }
email { Faker::Internet.email }
end
end
#spec/models/user_spec.rb
# in this test structure, Faker returns duplicate emails
describe "nested describe blocks" do
describe "block 1" do
it "creates faker duplicates" do
10.times{
FactoryGirl.create(:student)
}
end
end
describe "block 2" do
it "creates faker duplicates" do
10.times{
FactoryGirl.create(:student)
}
end
end
end
# in this structure, Faker emails are unique
describe "no nested describe blocks" do
it "doesn't create duplicates" do
10.times{
FactoryGirl.create(:student)
}
end
it "doesn't create duplicates" do
10.times{
FactoryGirl.create(:student)
}
end
end
Rspec returns the following error:
Failure/Error: FactoryGirl.create(:student)
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken, Email has already been taken, Authentication token has already been taken
Upvotes: 4
Views: 3153
Reputation: 34327
Faker will still generate duplicate emails eventually. You can either use sequences or check that the email does not yet exist. See Faker is producing duplicate data when used in factory_girl
Upvotes: 0
Reputation: 654
@Dyanisse As you said we need to do following configuration in spec_helper.rb
config.use_transactional_fixtures = true
but Only that is not sufficient. We need to add it in curly brackets to re-evaluate it as follows
auth_token { Faker::Lorem.characters(32) }
It won't work with:
auth_token Faker::Lorem.characters(32)
Upvotes: 3
Reputation: 124
After a few hours banging my head on the table, my colleague found the answer:
Why isn't factory_girl operating transactionally for me? - rows remain in database after tests
The factories turned out not to be transactional. The issue disappeared after the following line to spec_helper.rb:
config.use_transactional_fixtures = true
Upvotes: 3