title: RSpec tests on has_secure_password strange behaviour
body: <p>I'm developing a RoR 4 application, following Michael Hartl's tutorial.</p>
  
  <p>When implementing the user authentication tests, everything goes fine. I have a few more mandatory fields than in the book, here is the model:</p>
  
  <pre><code>class User &lt; ActiveRecord::Base
    before_save { self.email = email.downcase }
  
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    validates :playground_id, presence: true
    validates :default_playground_id, presence: true
    validates :active_from, presence: true
    validates :active_to, presence: true
    validates :last_name, presence: true, length: { maximum: 100 }
    validates :login, presence: true, uniqueness: true, length: { maximum: 30 }
    validates :email, presence: true, uniqueness: true, length: { maximum: 100 }, format: { with: VALID_EMAIL_REGEX }
    validates :directory_id, length: { maximum: 100 }
    validates :first_name, length: { maximum: 100 }
    validates :password_digest, length: { maximum: 100 }
    validates :remember_token, length: { maximum: 100 }
    validates :created_by, length: { maximum: 30 }
    validates :updated_by, length: { maximum: 30 }
  
    has_secure_password
  
  end
  </code></pre>
  
  <p>Here are the tests related to the authentication process only:</p>
  
  <pre><code>###USER6 to test that password is correctly managed
    describe "when password is not present" do
      before do
        @user = User.new(playground_id: 0, default_playground_id: 0, last_name: "Other User", login: "OTHER_USR", 
      email: "other@example.com", active_from: "2013-01-01", active_to: "2113-01-01", is_admin: 1.zero?,
                   password: " ", password_confirmation: " ")
      end
      it { should_not be_valid }
    end
  
    describe "when password doesn't match confirmation" do
      before { @user.password_confirmation = "mismatch" }
      it { should_not be_valid }
    end
  
    describe "with a password that's too short" do
      before { @user.password = @user.password_confirmation = "a" * 5 }
      it { should be_invalid }
    end
  
    describe "return value of authenticate method" do
      before { @user.save }
      let(:found_user) { User.find_by(email: @user.email) }
  
      describe "with valid password" do
        it { should eq found_user.authenticate(@user.password) }
      end
  
      describe "with invalid password" do
        let(:user_for_invalid_password) { found_user.authenticate("invalid") }
  
        it { should_not eq user_for_invalid_password }
        specify { expect(user_for_invalid_password).to be_false }
      end
    end
  
  ### end
  </code></pre>
  
  <p>Yes, it works fine! Here is the result of running the tests:</p>
  
  <pre><code>Failures:
  
    1) User model validation: with a password that's too short should be invalid
       Failure/Error: it { should be_invalid }
         expected invalid? to return true, got false
       # ./spec/models/user_spec.rb:171:in `block (3 levels) in &lt;top (required)&gt;'
  
  Finished in 0.28647 seconds
  37 examples, 1 failure
  
  Failed examples:
  
  rspec ./spec/models/user_spec.rb:171 # User model validation: with a password that's too short should be invalid
  
  Randomized with seed 18843
  </code></pre>
  
  <p><strong>Now, if I add the password length validation in the User model:</strong></p>
  
  <pre><code>...
    validates :created_by, length: { maximum: 30 }
    validates :updated_by, length: { maximum: 30 }
  
    has_secure_password
    validates :password, length: { minimum: 6 }
  
  end
  </code></pre>
  
  <p>Running the tests returns errors about undefined authenticate method, and even brakes tests that are not related to authentication:</p>
  
  <pre><code>...
    5) User model validation: return value of authenticate method with invalid password 
       Failure/Error: let(:user_for_invalid_password) { found_user.authenticate("invalid") }
       NoMethodError:
  
         undefined method `authenticate' for nil:NilClass
  
       # ./spec/models/user_spec.rb:183:in `block (4 levels) in &lt;top (required)&gt;'
       # ./spec/models/user_spec.rb:186:in `block (4 levels) in &lt;top (required)&gt;'
  
  Finished in 0.29266 seconds
  
  37 examples, 5 failures
  
  Failed examples:
  
  rspec ./spec/models/user_spec.rb:51 # User model validation: availability of mandatory fields should be valid
  rspec ./spec/models/user_spec.rb:135 # User model validation: when email format is valid should be valid
  rspec ./spec/models/user_spec.rb:179 # User model validation: return value of authenticate method with valid password 
  ...
  </code></pre>
  
  <p><strong>What is the reason for this, how can I solve it ?</strong></p>
  
  <p>Thanks for your help,</p>
  
  <p>Fred</p>
  
  <p>PS : the gemfile</p>
  
  <pre><code>source 'https://rubygems.org'
  ruby '2.0.0'
  
  gem 'rails', '4.0.0'
  gem 'bootstrap-sass', '2.3.2'
  gem 'sass-rails',   '~&gt; 4.0.0'
  gem 'coffee-rails', '~&gt; 4.0.0'
  gem 'uglifier', '2.1.2'
  gem 'bcrypt-ruby', '~&gt; 3.0.1'
  gem 'jquery-rails', '~&gt; 3.0.4'
  gem 'turbolinks', '1.3.0'
  gem 'jbuilder', '1.4.2'
  
  group :doc do
    gem 'sdoc', '0.3.20', require: false
  end
  
  # gem for dev and test only
  group :development, :test do
    gem 'sqlite3', :require =&gt; 'sqlite3'
    gem 'annotate', '2.5.0'
    gem 'rspec-rails', '2.14.0'
    gem 'selenium-webdriver', '2.33.0'
    gem 'capybara', '2.1.0'
    gem 'factory_girl_rails', '4.2.0'
  end
  </code></pre>