非常简单,我正在使用工厂女孩来做以下事情:
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
答案 0 :(得分:3)
从班级attr_accessor :password
中移除User
。
由于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
未保存在数据库中。请务必从attr_accessor
模型中移除User
,以便将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
的原因。