【问题标题】:Factory Girl Passing nil to user model工厂女孩将 nil 传递给用户模型
【发布时间】:2014-04-06 15:51:13
【问题描述】:

很简单,我正在使用工厂女孩来做以下事情:

FactoryGirl.define do
    sequence :user_email do |n|
        "user#{n}@example.com"
    end

    # Allows for multiple user names
    sequence :user_name do |n|
        "user#{n}"
    end

    factory :user, class: Xaaron::User do
        first_name 'Adam'
        last_name 'Something'
        user_name {generate :user_name}
        email {generate :user_email}
        password 'somePasswordThat_Is$ecure10!'
    end
end

然后我们将这些信息传递给用户模式:

require 'bcrypt'

module Xaaron
  class User < ActiveRecord::Base
    attr_accessor :password

    before_save :encrypt_password

    validates :first_name, presence: true
    validates :user_name, uniqueness: true, presence: true, length: {minimum: 5}
    validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
    validates_uniqueness_of :user_name
    validates_uniqueness_of :email
    validates :password, presence: true, confirmation: true, length: { minimum: 10 }, if: :new_record?

    def self.authenticate_user(user_name, password)
        user = Xaaron::User.find_by_user_name(user_name)
        if(user && user.password == BCrypt::Engine.hash_secret(password, user.salt))
            user
        else
            nil
        end
    end

    def encrypt_password
        if password.present?
            self.salt = BCrypt::Engine.generate_salt
            self.password = BCrypt::Engine.hash_secret(password, salt)
        end
    end
  end
end

从那里开始,任何测试用户密码验证或查看我们生成的密码是否与我们存储在数据库中的密码相同的测试失败,因为工厂女孩通过了nil 到数据库。

测试输出失败

  5) Xaaron::User Validation checks should validate a user based on login credentials
     Failure/Error: Xaaron::User.authenticate_user(@user.user_name, @user.password).should == @user
       expected: #<Xaaron::User id: 5, first_name: "Adam", last_name: "Something", user_name: "user9", email: "user8@example.com", password: nil, salt: "$2a$10$Y1m4YK.4znWVz2icp0ENtO", created_at: "2014-04-06 15:20:53", updated_at: "2014-04-06 15:20:53">
            got: nil (using ==)
     # ./spec/models/xaaron/user_spec.rb:33:in `block (3 levels) in <top (required)>'

您可以在上面看到:password: nil 它不应该是......

导致失败的测试

it "should validate a user based on login credentials" do
  @user = FactoryGirl.create(:user)
  Xaaron::User.authenticate_user(@user.user_name, @user.password).should == @user
end

根据要求 - 架构

ActiveRecord::Schema.define(version: 20140323000123) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "xaaron_users", force: true do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.string   "user_name"
    t.string   "email"
    t.string   "password"
    t.string   "salt"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

【问题讨论】:

  • 你能分享schema.rb的用户架构吗?另外,如果您想在聊天中讨论这个问题,请加入我 chat.stackoverflow.com/rooms/48530/ror
  • @KirtiThorat 我分享了引擎的架构。

标签: ruby-on-rails-4 rspec factory-bot


【解决方案1】:

User 类中删除 attr_accessor :password。 由于 ActiveRecord 会将其视为虚拟属性,因此不会保存在数据库中。

如果您注意到收到 rspec 失败消息:

expected: #<Xaaron::User id: 5, first_name: "Adam", last_name: "Something", user_name: "user9", email: "user8@example.com", password: nil, salt: "$2a$10$Y1m4YK.4znWVz2icp0ENtO", created_at: "2014-04-06 15:20:53", updated_at: "2014-04-06 15:20:53">

password 未保存在数据库中。确保从User 模型中删除attr_accessor,以便password 被视为字段并将保存在数据库中。

接下来,您需要更新示例如下:

it "should validate a user based on login credentials" do
  @user = FactoryGirl.create(:user)
  @login_user = FactoryGirl.build(:user) 
  Xaaron::User.authenticate_user(@user.user_name, @login_user.password).should == @user 
end

@user 包含在数据库中创建的实际记录,因此@user.password 已经具有加密密码。您的示例失败,因为您将加密密码发送到 authenticate_user 方法并重新加密已经加密的密码

BCrypt::Engine.hash_secret(password, user.salt)

实际上,为了让您的示例传递您需要传递的是实际密码没有任何加密。这就是我在您的示例中添加@login_user 的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多