Edit
Using the answers to the question I changed the test to the following which tests correctly and passes..
describe "when email is already taken" do
let(:user_with_same_email) { @user.dup }
before do
user_with_same_email.email.upcase!
user_with_same_email.save
end
it { user_with_same_email.should_not be_valid }
end
Note: Not using let(:user_with_same_email) { @user.dup } makes the test fail as it cannot find the variable user_with_same_email if it’s simply duplicated in the before block as in the chosen answer to this question.
I have a User model and a user_spec.rb test file which has various validations against the User models attributes.
Previously I was writing the following at the top of my user_spec.rb file to test the User model:
describe User do
before do
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar88", password_confirmation: "foobar88")
end
...
I wanted to move this model creation to FactoryGirl so I created a factories.rb file:
FactoryGirl.define do
factory :user do
name "foo"
email { "#{name}@example.com" }
password "foobar99"
password_confirmation "foobar99"
end
end
I then changed my user_spec.rb:
describe User do
before do
@user = FactoryGirl.create(:user)
end
...
Now every test passes as before except one:
describe "when email 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
Now unless `FactoryGirl is skipping my email uniqueness validation I can’t figure out what is going wrong here.
My User model validation code:
class User < ActiveRecord::Base
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i unless const_defined?(:VALID_EMAIL_REGEX)
has_secure_password
attr_accessible :name, :email, :password, :password_confirmation
has_many :programs
before_save { self.email.downcase! }
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
The problem is that when you say it { should_not be_valid }, RSpec checks the subject. in this case the subject is User.new (you have “describe User” at the top so unless you specified something else this is the default).
You want to check the user_with_same_email for validity instead.
edit:
Try this, I think it might work: