测试抱怨NoMethodError:nil的未定义方法`name':NilClass

时间:2014-02-15 22:24:12

标签: ruby-on-rails ruby unit-testing

刚刚向数据库添加了bcryptpassword_digest列。现在我收到了这个错误。它说它不承认名字,这个测试正在通过。现在它失败了。所有其他测试都通过了(包括password_digest中的一个,奇怪的是)。我正在使用rails附带的测试框架。

  def test_can_create_profiles
    user = create_user('tester@test.com', 'hassan') #creates a profile with randomized password
    assert_equal "hassan", User.find_by_email('tester@test.com').name
  end 

捆绑exec rake测试

  1) Error:
UserTest#test_can_create_profiles:
NoMethodError: undefined method `name' for nil:NilClass
    test/models/user_test.rb:9:in `test_can_create_profiles'



class User < ActiveRecord::Base
  email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  before_save {self.email = email.downcase}  
  validates :name, presence: true, length: { maximum: 20 }
  validates :email, :presence => true,
    :format => { :with => email_regex },
    :uniqueness => { :case_sensitive =>
      false }
  has_secure_password
end

如果有任何信息,我遗漏了pelase让我知道。


def create_user(email, name)
  user = User.new(name: name, email: email)
  user.password_digest = (0...8).map { (65 + rand(26)).chr }.join
  user.save
  user
end

AGHH

x = User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil>
irb(main):002:0> x.name ='lol'
=> "lol"
irb(main):005:0> x.email = 'apple@ape.com'
=> "apple@ape.com"

irb(main):007:0> x.password_digest = 'lol'
=> "lol"
irb(main):008:0> x.save
   (0.1ms)  begin transaction
  User Exists (0.3ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('apple@ape.com') LIMIT 1
   (0.1ms)  rollback transaction
=> false

好的,问题就在这里的某个地方!

irb(main):010:0> raise x.errors.inspect
RuntimeError: #<ActiveModel::Errors:0x007f6fae5b3bf8 @base=#<User id: nil, name: "lol", email: "apple@ape.com", created_at: nil, updated_at: nil, password_digest: "lol">, @messages={:password=>["can't be blank"]}>

irb(main):013:0> raise x.password= 'hello'
RuntimeError: hello
    from (irb):13
    from /home/user/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/railties-4.0.1/lib/rails/commands/console.rb:90:in `start'
    from /home/user/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/railties-4.0.1/lib/rails/commands/console.rb:9:in `start'
    from /home/user/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/railties-4.0.1/lib/rails/commands.rb:62:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'
irb(main):014:0> raise x.errors.inspect
RuntimeError: #<ActiveModel::Errors:0x007f6fae5b3bf8 @base=#<User id: nil, name: "lol", email: "apple@ape.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$CMPQdQSLKQTS5r0G2a1oheDhblzxcp65KxStZbKKAHmy...">, @messages={:password=>["can't be blank"]}>
    from (irb):14
    from /home/user/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/railties-4.0.1

呃:c

为什么会这样?

编辑:bcrypt需要填写密码和password_confirmation字段。

这就是造成麻烦的原因,以及破坏的测试。 &GT;。&LT;

2 个答案:

答案 0 :(得分:2)

假设您的create_user方法成功保存了User个对象,那么您的问题很简单:

您要保存电子邮件地址tester@test.com并尝试检索test@test.com

如果仍无法解决问题,请发布您的create_user方法。

答案 1 :(得分:1)

您已在密码上添加了状态验证,因此您需要在保存之前进行设置。您目前正在设置password_digest - 您不应该这样做。摘要是加密密码,在分配密码时生成。因此:

def create_user(email, name)
  user = User.new(name: name, email: email)
  user.password = (0...8).map { (65 + rand(26)).chr }.join
  # user.password_confirmation = user.password     # You might need this as well
  user.save!    # To avoid this kind of errors in the future use banged save
  user