rspec test failure when switching from initializing attributes to Factory
factory-bot, railstutorial.org, rspec, ruby-on-rails-3, testing
Solution
The factory puts the record in the DB. User.new doesn't until it is saved. The original test doesn't check if user_with_same_email gets created, rather that 'it' (subject { @user }) can't be created because the email exists. After making your change to the @user, I had to rewrite the test:
describe "when email address is already taken" do
let (:user_with_same_email) { @user.dup }
specify { user_with_same_email.should_not be_valid }
end
Problem
This makes no sense to me, hope someone can help. I'm getting a single test failure when creating a user using a factory (seemingly similar tests pass). In my user_spec.rb test file, the user was originally created like this. Using this initialization approach, all tests pass. USER CREATION user_spec.rb (without factory) ``` describe User do before do @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar", username: "username") end ``` Most of the other tests for the app use factories. So, decided to replace the above with call to factory. user_spec.rb (with factory) ``` describe User do before do @user = FactoryGirl.create(:user) end ``` FACTORY The factory looks like this. factories.rb ``` FactoryGirl.define do factory :user do sequence(:name) { |n| "Person #{n}" } sequence(:email) { |n| "person_#{n}@example.com" } password "foobar" password_confirmation "foobar" sequence(:username) { |n| "username_#{n}" } ``` TEST FAILURE Here is the test failure when using the factory to create the user. user_spec.rb ``` Failures: 1) 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:101:in `block (3 levels) in <top (required)>' Finished in 12.61 seconds 178 examples, 1 failure, 2 pending ``` TEST Here is the part of the test that fails when switching to the factory. ``` 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 ``` INSPECTION OF USER AND USER.DUP My first thought was perhaps using the .dup on the factory created user was causing problems. Here is the @user and the @user.dup when output from their use in the test above (by adding the lines `puts @user.inspect` and `puts user_with_same_email.inspect` into the describe block. Both of these `puts` are after the `user_with_same_email.save`). WITHOUT FACTORY (Test passes) @user ``` #<User id: nil, name: "Example User", email: "user@example.com", created_at: nil, updated_at: nil, password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...", remember_token: nil, admin: false, username: "username"> ``` user_with_same_email ``` #<User id: 1178, name: "Example User", email: "USER@EXAMPLE.COM", created_at: "2012-04-24 06:01:07", updated_at: "2012-04-24 06:01:07", password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...", remember_token: "rMS9jM0d4lobLc-A-pTTqA", admin: false, username: "username"> ``` WITH FACTORY (Test fails) @user ``` #<User id: 739, name: "Person 67", email: "person_67@example.com", created_at: "2012-04-24 05:54:28", updated_at: "2012-04-24 05:54:28", password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...", remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67"> ``` user_with_same_email ``` #<User name: "Person 67", email: "PERSON_67@EXAMPLE.COM", created_at: nil, updated_at: nil, password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...", remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67"> ``` What stands out above is that @user is not already saved without using the factory, whereas when using the factory @user is saved. I'm just not seeing how this effects the test in this case. Any help would be appreciated. Thanks! (The above code comes from Michael Hartl's Rails Tutorial, I'm working on some of the app feature extensions he mentions at the end of the tutorial.)