2013-05-20 51 views
3

所以,我一直在RSpec作爲NoMethodError返回的'authenticate'方法的問題。以下是我的代碼。我從Michael Hartl的Rails教程中大量借用,因爲我剛剛學習Rails和RSpec。rails認證nilthoderror nil爲nilClass

我加入「has_secure_password」我的用戶模型告訴記者,在哈特爾的教程中,我已經成功地創建了一個用戶與password_digest,因此該方法是功能性的。測試將變得棘手。不知怎的,我想知道我是否安裝了RSpec。我已經按照教程來開球,但沒有出現這樣的錯誤。關於爲什麼會發生這種情況的任何想法?

我User_spec.rb:

require 'spec_helper' 

describe User do 

    before do 
    @user = User.new(name: "Example User", email: "[email protected]") 
    end 

    subject { @user } 

    it { should respond_to(:name) } 
    it { should respond_to(:email) } 
    it { should respond_to(:password_digest) } 
    it { should respond_to(:password) } 
    it { should respond_to(:password_confirmation) } 
    it { should respond_to(:authenticate) } 

    it { should be_valid } 

    describe "when name is not present" do 
    before { @user.name = ' ' } 
    it { should_not be_valid} 
    end 

    describe "name is too long" do 
    before { @user.name = "a" * 51 } 
    it { should_not be_valid } 
    end 

    describe "when email format is valid" do 
    it "should be valid" do 
     addresses = %w[[email protected] [email protected] [email protected] [email protected]] 
     addresses.each do |valid_address| 
      @user.email = valid_address 
      @user.should be_valid 
    end 
    end 
end 

    describe "when email format is invalid" do 
    it "should be invalid" do 
     addresses = %w[[email protected],com user_at_foo.org [email protected] 
        [email protected]_baz.com [email protected]+baz.com] 
     addresses.each do |invalid_address| 
      @user.email = invalid_address 
      @user.should_not be_valid 
     end 
    end 
    end 

    describe "when email is 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 

    describe "when password is not present" do 
    before { @user.password = @user.password_confirmation = " " } 
    it { should_not be_valid } 
    end 

    describe "when password doesn't match confirm" do 
    before { @user.password_confirmation = "mismatch" } 
    it { should_not be_valid } 
    end 

    describe "when password confirm is nil" do 
    before { @user.password_confirmation = nil } 
    it { should be_invalid } 
    end 

    describe "with a password that's too short" do 
    before { @user.password = @user.password_confirmation = "a" * 5 } 
    it { should_not be_valid } 
    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 == 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 

和我的Gemfile:

source 'https://rubygems.org' 

gem 'rails', '3.2.13' 
# To use ActiveModel has_secure_password 
gem 'bcrypt-ruby', '3.0.1' 
gem 'bootstrap-sass', '2.1' 
# Bundle edge Rails instead: 
# gem 'rails', :git => 'git://github.com/rails/rails.git' 

group :development, :test do 
    gem 'sqlite3', '1.3.5' 
    gem 'rspec-rails', '2.11.0' 
    gem 'guard-rspec', '1.2.1' 
    gem 'guard-spork', '1.2.0' 
    gem 'childprocess', '0.3.6' 
    gem 'spork', '0.9.2' 
end 

group :development do 
    gem 'annotate', '2.5.0' 
end 

# Gems used only for assets and not required 
# in production environments by default. 
group :assets do 
    gem 'sass-rails', '3.2.5' 
    gem 'coffee-rails', '3.2.2' 
    gem 'uglifier', '1.2.3' 
end 
    # See https://github.com/sstephenson/execjs#readme for more supported runtimes 
    # gem 'therubyracer', :platforms => :ruby 

gem 'jquery-rails', '2.0.2' 

group :test do 
    gem 'capybara', '1.1.2' 
    gem 'rb-inotify', '0.9' 
    gem 'libnotify', '0.5.9' 
end 

group :production do 
    gem 'pg', '0.12.2' 
end 


# To use Jbuilder templates for JSON 
# gem 'jbuilder' 

# Use unicorn as the app server 
# gem 'unicorn' 

# Deploy with Capistrano 
# gem 'capistrano' 

# To use debugger 
# gem 'debugger' 

我的用戶模型:

class User < ActiveRecord::Base 
attr_accessible :email, :name, :password, :password_confirmation 
has_secure_password 
before_save { |user| user.email = email.downcase } 

validates :name, presence: true, length: { maximum: 50 } 
VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 
validates :email, presence: true, 
       uniqueness: { case_sensitive: false }, 
       format: { with: VALID_EMAIL_REGEX } 
validates :password, presence: true, length: { minimum: 6 } 
validates :password_confirmation, presence: true 

end 

,下面將我從RSpec的

看到的錯誤
1) User 
    Failure/Error: it { should be_valid } 
     expected valid? to return true, got false 
    # ./spec/models/user_spec.rb:29:in `block (2 levels) in <top (required)>' 

    2) User 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:101:in `block (4 levels) in <top (required)>' 
    # ./spec/models/user_spec.rb:104:in `block (4 levels) in <top (required)>' 

    3) User 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:101:in `block (4 levels) in <top (required)>' 
    # ./spec/models/user_spec.rb:103:in `block (4 levels) in <top (required)>' 

    4) User return value of authenticate method with valid password 
    Failure/Error: it { should == found_user.authenticate(@user.password) } 
    NoMethodError: 
     undefined method `authenticate' for nil:NilClass 
    # ./spec/models/user_spec.rb:97:in `block (4 levels) in <top (required)>' 

    5) User when email format is valid should be valid 
    Failure/Error: @user.should be_valid 
     expected valid? to return true, got false 
    # ./spec/models/user_spec.rb:46:in `block (4 levels) in <top (required)>' 
    # ./spec/models/user_spec.rb:44:in `each' 
    # ./spec/models/user_spec.rb:44:in `block (3 levels) in <top (required)> 

UPDATE:

編輯實例用戶爲解決這樣的問題:

before do 
    @user = User.new(name: "Example User", email: "[email protected]", 
     password: "foobar", password_confirmation: "foobar") 
    end 
+0

謝謝我被困在相同的NIL問題:-) – mahatmanich

回答

2

在用戶模式你驗證密碼的存在所以在你的天賦,你應該在一傳新用戶對象的密碼。那麼它應該是有效的。

我猜這就是你運行與認證方法的問題以及原因。

+0

就這麼簡單。謝謝! –

相關問題