Reputation: 11207
Mike Hartl's book gives the below for Listing 6.17 for a test for the rejection of duplicate email addresses, insensitive to case.
The call to User.new
creates an in memory user but nowhere is @user.save
called to save it to the database.
Running the test, it correctly rejects the duplicate address. But I can't figure out how it works. Only user_with_same_email
is saved to the database not @user
. So how could the validity test detect the duplicate without @user
saved?
require 'spec_helper'
describe User do
before do
@user = User.new(name: "Example User", email: "[email protected]")
end
subject { @user }
.
.
.
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
end
Upvotes: 1
Views: 91
Reputation: 11494
The object @user
need not be saved to run the validity check. The rspec expression it { should_not be_valid }
calls @user.valid?
under the hood. This method can be run on an ActiveRecord instance whether or not it has been saved.
Upvotes: 1
Reputation: 53038
user_with_same_email
is actually saved in the database.
Notice that subject is @user
.
subject { @user }
Hence, example it { should_not be_valid }
is executed on implied subject which is @user
.
@user.valid?
returns false as you have put uniqueness constraint
on the email address
and there is already a record with same email address in your database(recall user_with_same_email
that was saved).
So, your test example passes as @user
is not valid.
Upvotes: 3