Rails 3教程第6章奇怪的Rspec失败

时间:2012-09-24 18:42:24

标签: ruby-on-rails ruby rspec

我和Rails tutoril打架。我坚持第6章。这是问题所在 当我运行测试时:

bundle exec rspec spec/models/user_spec.rb

I get few failures:

 Failures:

 1) User
 ←[31mFailure/Error:←[0m ←[31mit { should be_valid }←[0m
 ←[31mexpected valid? to return true, got false←[0m
 ←[36m     # ./spec/models/user_spec.rb:31:in `block (2 levels) in <top (required
 )>'←[0m

 2) User when email format is valid should be valid
 ←[31mFailure/Error:←[0m ←[31m@user.should be_valid←[0m
   ←[31mexpected valid? to return true, got false←[0m
 ←[36m     # ./spec/models/user_spec.rb:64:in `block (4 levels) in <top (required
 )>'←[0m
 ←[36m     # ./spec/models/user_spec.rb:62:in `each'←[0m
 ←[36m     # ./spec/models/user_spec.rb:62:in `block (3 levels) in <top (required
 )>'←[0m

 3) User return value of authenticate method with valid password
 ←[31mFailure/Error:←[0m ←[31mit { should == found_user.authenticate(@user.p
 assword) }←[0m
 ←[31mNoMethodError:←[0m
   ←[31mundefined method `authenticate' for nil:NilClass←[0m
 ←[36m     # ./spec/models/user_spec.rb:99:in `block (4 levels) in <top (required
 )>'←[0m

 4) User return value of authenticate method with invalid password
 ←[31mFailure/Error:←[0m ←[31mlet(:user_for_invalid_password) { found_user.a
 authenticate("invalid") }←[0m
 ←[31mNoMethodError:←[0m
   ←[31mundefined method `authenticate' for nil:NilClass←[0m
 ←[36m     # ./spec/models/user_spec.rb:103:in `block (4 levels) in <top (require
 d)>'←[0m
 ←[36m     # ./spec/models/user_spec.rb:105:in `block (4 levels) in <top (require
 d)>'←[0m

 5) User return value of authenticate method with invalid password
 ←[31mFailure/Error:←[0m ←[31mlet(:user_for_invalid_password) { found_user.a
 uthenticate("invalid") }←[0m
 ←[31mNoMethodError:←[0m
   ←[31mundefined method `authenticate' for nil:NilClass←[0m
 ←[36m     # ./spec/models/user_spec.rb:103:in `block (4 levels) in <top (require
 d)>'←[0m
 ←[36m     # ./spec/models/user_spec.rb:106:in `block (4 levels) in <top (require
 d)>'←[0m

 6) User return value of authenticate method with valid password
 ←[31mFailure/Error:←[0m ←[31mit { should == found_user.authenticate(@user.e
 mail) }←[0m
 ←[31mNoMethodError:←[0m
   ←[31mundefined method `authenticate' for nil:NilClass←[0m
 ←[36m     # ./spec/models/user_spec.rb:120:in `block (4 levels) in <top (require
 d)>'←[0m

 7) User return value of authenticate method with invalid password
 ←[31mFailure/Error:←[0m ←[31mlet(:user_for_invalid_password) { found_user.a
 uthenticate("invalid") }←[0m
 ←[31mNoMethodError:←[0m
   ←[31mundefined method `authenticate' for nil:NilClass←[0m
 ←[36m     # ./spec/models/user_spec.rb:124:in `block (4 levels) in <top (require
 d)>'←[0m
 ←[36m     # ./spec/models/user_spec.rb:126:in `block (4 levels) in <top (require
 d)>'←[0m

 8) User return value of authenticate method with invalid password
 ←[31mFailure/Error:←[0m ←[31mlet(:user_for_invalid_password) { found_user.a
 uthenticate("invalid") }←[0m
 ←[31mNoMethodError:←[0m
   ←[31mundefined method `authenticate' for nil:NilClass←[0m
 ←[36m     # ./spec/models/user_spec.rb:124:in `block (4 levels) in <top (require
 d)>'←[0m
 ←[36m     # ./spec/models/user_spec.rb:127:in `block (4 levels) in <top (require
 d)>'←[0m

 9) User with a password that's too short
 ←[31mFailure/Error:←[0m ←[31mit { should be_valid }←[0m
   ←[31mexpected valid? to return true, got false←[0m
 ←[36m     # ./spec/models/user_spec.rb:112:in `block (3 levels) in <top (require
 d)>'←[0m

 Finished in 8.5 seconds
 ←[31m23 examples, 9 failures←[0m

 Failed examples:

 ←[31mrspec ./spec/models/user_spec.rb:31←[0m ←[36m# User ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:60←[0m ←[36m# User when email format is va
 lid should be valid←[0m
 ←[31mrspec ./spec/models/user_spec.rb:99←[0m ←[36m# User return value of authent
 icate method with valid password ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:105←[0m ←[36m# User return value of authen
 ticate method with invalid password ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:106←[0m ←[36m# User return value of authen
 ticate method with invalid password ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:120←[0m ←[36m# User return value of authen
 ticate method with valid password ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:126←[0m ←[36m# User return value of authen
 ticate method with invalid password ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:127←[0m ←[36m# User return value of authen
 ticate method with invalid password ←[0m
 ←[31mrspec ./spec/models/user_spec.rb:112←[0m ←[36m# User with a password that's
 too short ←[0m

我的User_spec.rb

require '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 respond_to(:authenticate) }

it { should be_valid }

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
    end
end

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

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

 My user.rb model:

   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+\-.]+@[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

请有人帮忙!我已经坚持了这个问题大约两个星期,仍然不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

我认为它是您的VALID_EMAIL_REGEX区域

你有:

VALID_EMAIL_REGEX = /\A[w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

Github:

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

https://github.com/railstutorial/sample_app_2nd_ed/blob/master/app/models/user.rb

评论编辑 - 如果我是你,我会从github复制相关位,或者至少比较那些有错误的位。

来自github:

describe "with a password that's too short" do
  before { @user.password = @user.password_confirmation = "a" * 5 }
  it { should be_invalid }
end

从您的应用

describe "with a password that's too short" do
  before { @user.password = @user.password_confirmation = "a" * 5 }
  it { should be_valid }
end

答案 1 :(得分:0)

同时检查你是否已正确初始化了@user,在本章的第6章末尾, 在user_spec.rb中,初始化应该如下,

之前

    @user = User.new(name: "Example User", email: "user@example.com",password: "foobar", password_confirmation: "foobar")
  end

请注意,应传递所有必需的用户属性(在本例中为name,email,password和password_confirmation)