質問

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: "user@example.com")
  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
役に立ちましたか?

解決 2

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.

他のヒント

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top