I’m testing my User model and studying how FactoryGirl works. When I do this in my user_spec.rb:
before(:each) do
@user = User.new(username: 'ExampleUser', email: 'user@example.com', timezone: 'Eastern Time (US & Canada)', password: 'example')
end
Everything passes, but if I do:
before(:each) do
@user = FactoryGirl.create(:user)
end
It fails the test to see if the user’s username and email are taken already.
1) User when username is already taken
Failure/Error: it { should_not be_valid }
expected valid? to return false, got true
# ./spec/models/user_spec.rb:151:in `block (3 levels) in <top (required)>'
2) User when email address is already taken
Failure/Error: it { should_not be_valid }
expected valid? to return false, got true
# ./spec/models/user_spec.rb:142:in `block (3 levels) in <top (required)>'
Finished in 1.8 seconds
29 examples, 2 failures
These are the test:
describe 'when email address is already taken' do
before do
user_with_same_email = @user.dup
user_with_same_email.email = @user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end
describe 'when username is already taken' do
before do
user_with_same_username = @user.dup
user_with_same_username.username = @user.username.upcase
user_with_same_username.save
end
it { should_not be_valid }
end
Can someone explain? I thought FactoryGirl was suppose to let me use it like User.new, my first example which works.
FactoryGirl.createactually creates the record, whereasUser.newonly instantiates the model but does not actually save the record.If you want to only instantiate the model, you should use
FactoryGirl.build:See the documentation for details.
So what I think is happening with your current code is that when you create the user with
FactoryGirl.create, it actually saves the record with no validation issues (since the duplicate has not been created yet). When you save the user with the same email withuser_with_same_email.save, it does not actually save that user but you don’t see that. Then when you check if the original user is valid, it says yes because you already saved it before trying (and failing) to create the duplicate.Make sense? Anyway just switch to
FactoryGirl.buildand both tests should pass.