【问题标题】:Test complaining NoMethodError: undefined method `name' for nil:NilClass测试抱怨 NoMethodError: undefined method `name' for nil:NilClass
【发布时间】:2014-02-16 08:40:29
【问题描述】:

刚刚将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

如果有任何我遗漏的信息请告诉我。


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

哎呀

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 需要填写密码和密码确认字段。

这就是造成麻烦的原因,也是测试失败的原因。 >.

【问题讨论】:

  • 向我们展示您的 create_user 方法 - 看起来它正在创建未保存到数据库的无效用户。
  • 你是对的,它没有保存。我只是试图从控制台做到这一点! :c 不知道为什么
  • user.save 之后添加raise user.errors.inspect 你应该明白为什么了。 :)

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


【解决方案1】:

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

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

如果这不能解决问题,请发布您的 create_user 方法。

【讨论】:

  • 啊。你说的对!但是我不认为我的方法是在拯救用户……>.
  • @user2783087 如果它对您有用,您应该接受答案,并且不要在问题中指出已解决
【解决方案2】:

您已在密码上添加了存在验证,因此您需要在保存前进行设置。您当前正在设置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

结束

【讨论】:

    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2012-08-08
    • 2014-09-05
    • 1970-01-01
    相关资源
    最近更新 更多