rails tutorial第2版。第6.3.4章

时间:2013-05-08 14:08:40

标签: ruby-on-rails ruby rspec railstutorial.org

我希望有人可以提供帮助。我正在阅读Michael Hartl的rails教程书,我被困在chapter 6.3.4。我试图让所有测试验证,我不断收到几个错误。我已经发布了错误消息以及我的user.rb和user_spec.rb文件以供参考。 希望有人能看到我出错的地方。任何帮助将不胜感激。

错误

Failures:

  1) when email address is already taken
     ←[31mFailure/Error:←[0m ←[31muser_with_same_email = @user.dup←[0m
     ←[31mTypeError:←[0m
       ←[31mcan't dup NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:69:in `dup'←[0m
←[36m     # ./spec/models/user_spec.rb:69:in `block (5 levels) in <top (required
)>'←[0m

  2) when password is not present
     ←[31mFailure/Error:←[0m ←[31mbefore { @user.password = @user.password_confi
rmation = " " }←[0m
     ←[31mNoMethodError:←[0m
       ←[31mundefined method `password_confirmation=' for nil:NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:78:in `block (5 levels) in <top (required
)>'←[0m

  3) when password doesn't match confirmation
     ←[31mFailure/Error:←[0m ←[31mbefore { @user.password_confirmation = "mismat
ch" }←[0m
     ←[31mNoMethodError:←[0m
       ←[31mundefined method `password_confirmation=' for nil:NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:83:in `block (5 levels) in <top (required
)>'←[0m

  4) when password confirmation is nil
     ←[31mFailure/Error:←[0m ←[31mbefore { @user.password_confirmation = nil }←[
0m
     ←[31mNoMethodError:←[0m
       ←[31mundefined method `password_confirmation=' for nil:NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:88:in `block (5 levels) in <top (required
)>'←[0m

  5) with a password that's too short
     ←[31mFailure/Error:←[0m ←[31mbefore { @user.password = @user.password_confi
rmation = "a" * 5 }←[0m
     ←[31mNoMethodError:←[0m
       ←[31mundefined method `password_confirmation=' for nil:NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:93:in `block (5 levels) in <top (required
)>'←[0m

  6) return value of authticate method with valid password
     ←[31mFailure/Error:←[0m ←[31mbefore { @user.save }←[0m
     ←[31mNoMethodError:←[0m
       ←[31mundefined method `save' for nil:NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:98:in `block (5 levels) in <top (required
)>'←[0m

  7) return value of authticate method with invalid password
     ←[31mFailure/Error:←[0m ←[31mbefore { @user.save }←[0m
     ←[31mNoMethodError:←[0m
       ←[31mundefined method `save' for nil:NilClass←[0m
←[36m     # ./spec/models/user_spec.rb:98:in `block (5 levels) in <top (required
)>'←[0m

user.rb文件

class User < ActiveRecord::Base
  attr_accessible :name, :email, :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+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
 validates :email,  presence: true,
                    format: { with: VALID_EMAIL_REGEX }, 
                    uniqueness: { case_sensitive: false }
 validates :password, presence: true, length: { minimum: 6 }
 validates :password_confirmation, presence: true                   
end

user_spec.rb

要求'spec_helper'

describe User do

    before do
        @user = User.new(   name: "Example User", email: "user@example.com", 
                            password: "foobar", password_confirmation: "foobar")
    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 be_valid }

        it { should respond_to(:authenticate) }

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

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

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

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

        describe "when email format is valid" do
            it "should be valid" do
                addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
                addresses.each do |valid_address|
                    @user.email = valid_address
                    @user.should be_valid
        end 

        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

        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 confirmation" do
            before { @user.password_confirmation = "mismatch" }
            it { should_not be_valid }
        end 

        describe "when password confirmation is nil" do
            before { @user.password_confirmation = nil }
            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 authticate 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") }
            specify { user_for_invalid_password.should be_false }
        end

        end             
    end
end     

1 个答案:

答案 0 :(得分:0)

在您的user.rb中,您的验证语法不正确。

编辑 - 此外,直接检查他的代码与您的代码。他有git repository here

  • 看起来你的user_spec与他的相比也存在一些不同的差异。

而不是:

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 }
validates :password, presence: true, length: { minimum: 6 }
validates :password_confirmation, presence: true 

这样做:

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 }

validates :password, :presence => true, 
                     :length => { :minimum => 6 }

validates :password_confirmation, :presence => true