Rails - 使用 Rspec 和 Devise 测试用户模型

Rails - Testing User Model with Rspec and Devise

我正在尝试测试用户创建的用户模型规范

factories/users.rb

FactoryGirl.define do
  factory :user do
    first_name {Faker::Name.first_name}
    last_name {Faker::Name.last_name}
    email {Faker::Internet.email}
    username {Faker::Internet.user_name}
    password {Faker::Internet.password}
  end

end

specs/models/user_spec.rb

require 'rails_helper'

describe User, :type => :model do

  context "valid Factory" do
    it "has a valid factory" do
      expect(build(:user)).to be_valid
    end
  end

  context "validations" do
    before { create(:user) }

    context "presence" do
      it { should validate_presence_of :first_name }
      it { should validate_presence_of :last_name }
      it { should validate_presence_of :email }
      it { should validate_presence_of :encrypted_password }
    end

    context "uniqueness" do
      it { should validate_uniqueness_of :email }
      it { should validate_uniqueness_of :username }
    end
  end
end

我正在使用 Devise 创建用户。但我最终得到以下 测试失败

User
  valid Factory
    has a valid factory
  validations
    presence
      should require first_name to be set
      should require last_name to be set
      should require email to be set
      should require encrypted_password to be set (FAILED - 1)
    uniqueness
      should require case sensitive unique value for email
      should require case sensitive unique value for username

Failures:

  1) User validations presence should require encrypted_password to be set
     Failure/Error: it { should validate_presence_of :encrypted_password }
       Expected errors to include "can't be blank" when encrypted_password is set to nil,
       got no errors
     # ./spec/models/user_spec.rb:18:in `block (4 levels) in <top (required)>'

Finished in 0.98827 seconds (files took 6.61 seconds to load)
7 examples, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:18 # User validations presence should require encrypted_password to be set

我假设 encrypted_password 将由 Devise 在尝试创建用户时自动生成。

Devise 实际上并不验证加密的密码,因为如果密码是 "dirty"(已更改),它是在验证后动态创建的。

您实际上不需要以那种方式测试加密密码,因为它是一个实现细节。您可以通过执行以下操作来测试可验证数据库是否正常工作:

it 'is database authenticable' do
  user = User.create(
     email: 'test@example.com', 
    password: 'password123',
    password_confirmation: 'password123'
  )
  expect(user.valid_password?('password123')).to be_truthy
end

但是测试的实际价值很低。相反,使用 Devise 时,您可能希望专注于某些 end-to-end tests (feature specs) 测试用户注册和登录路径的地方。

我建议您只测试您添加的那些验证,您不需要测试由设计添加的验证,因为它们已经过测试。