I am having a problem with the RSpec tests for user model at the end of section 6.3.4 of M. Hartl's Rails tutorial. I am absolutely lost please help.
All of the tests are passing apart from one that I need help with:
My question: Why rspec is getting different results from similar console operations and how can I fix this and pass the test?
Failures:
1) User return value of authenticate method with valid password
Failure/Error: it { should == found_user.authenticate(@user.password) } expected: User id: 1, name: "Example User", email: "[email protected]", created_at: "2013-08-21 21:38:32", updated_at: "2013-08-21 21:38:32", password_digest: "$2a$04$tjcti4yEYFuJbbz9sa.Z9.F/KXJtHU3A8onU1Fhovn3x..."> got: #User id: nil, name: "Example User", email: "[email protected]", created_at: nil, updated_at: nil, password_digest: "$2a$04$6fdtfzgCFYetjShfYKuFIObWo4Uru4xRMkhW7Ow92O.2...">
Finished in 0.64049 seconds 20 examples, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:100 # User return value of authenticate method with valid password
When I manually test it in rails console, authenticate method returns exactly the same user with all of the fields matching. Following is my console experiment:
Loading development environment in sandbox (Rails 4.0.0) Any modifications you make will be rolled back on exit irb(main):001:0>
user = User.new(name: "Example User", email: "[email protected]", password: "foobar", password_confirmation: "foobar")
=> #
irb(main):002:0> user.save
(0.3ms) SAVEPOINT active_record_1 User Exists (0.3ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1 Binary data inserted forstring
type on columnpassword_digest
SQL (48.2ms) INSERT INTO "users" ("created_at", "email", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", Wed, 21 Aug 2013 21:45:13 UTC +00:00], ["email", "[email protected]"], ["name", "Example User"], ["password_digest", "$2a$10$6tJCohmi7t3OShf/55S5Se98JWvGhJfC1wNAZsc8B6WPP1Zgee0wu"], ["updated_at", Wed, 21 Aug 2013 21:45:13 UTC +00:00]]
(0.2ms)RELEASE SAVEPOINT active_record_1 => true
irb(main):003:0> found_user = User.find_by_email(user.email)
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."email" = '[email protected]' LIMIT 1 => #
irb(main):004:0> user == found_user.authenticate(user.password)
=> true
This is what I have in spec/models/user_spec.rb
require 'spec_helper'
describe User do
before { @user = User.new(name: "Example User", email: "[email protected]", password: "foobar", password_confirmation: "foobar") }
subject { @user }
.
.
.
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 == found_user.authenticate(@user.password) }
end
describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end
.
.
.
end
User model is as follows
class User < ActiveRecord::Base
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true
end
Not sure if gem is important, here is what I have in mine:
source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0'
group :development do
gem 'annotate', '~> 2.4.1.beta'
end
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
# Bootstrap css framework from Twitter
gem 'bootstrap-sass', '2.0.0'
# RSpec testing framework
gem 'rspec-rails', '2.11.0'
gem 'capybara', '2.1.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
# Use ActiveModel has_secure_password
gem 'bcrypt-ruby', '3.0.1'
Thank you in advance, please let me know if I missed out on any other important bits of info.