首页 文章

为什么我的模型的唯一性验证规范在应该通过时失败?

提问于
浏览
1

我正在学习RSpec测试 . 有些东西不能用于我的测试 .

我的模特:

class User < ActiveRecord::Base
  has_secure_password

  # Validation macros
  validates_presence_of :name, :email
  validates_uniqueness_of :email, case_sensitive: false
end

我的工厂:

FactoryGirl.define do
  factory :user do
    name "Joe Doe"
    email "joe@example.com"
    password_digest "super_secret_password"
  end
end

而我的规格:

require 'rails_helper'

RSpec.describe User, type: :model do
  user = FactoryGirl.build(:user)

  it 'has a valid factory' do
    expect(FactoryGirl.build(:user)).to be_valid
  end

  it { is_expected.to respond_to(:name) }
  it { is_expected.to respond_to(:email) }
  it { is_expected.to respond_to(:password) }
  it { is_expected.to respond_to(:password_confirmation) }

  it { expect(user).to validate_presence_of(:name) }
  it { expect(user).to validate_presence_of(:email) }
  it { expect(user).to validate_presence_of(:password) }
  it { expect(user).to validate_uniqueness_of(:email).case_insensitive }
end

我希望这个测试能够通过 . 但是我得到了这个结果:

失败:1)用户应验证:电子邮件不区分大小写唯一失败/错误:它{expect(user).to validate_uniqueness_of(:email).case_insensitive}用户未正确验证:电子邮件不区分大小写 .
无法创建您提供的记录,因为它失败了
以下验证错误:

*名称:[“不能为空”]
#./spec/models/user_spec.rb:18:in在<top(required)>'中的块(2级)
完成0.34066秒(文件加载1.56秒)9个示例,1个失败失败示例:rspec ./spec/models/user_spec.rb:18#用户应验证:电子邮件不区分大小写

我错过了什么?

更新

我认为这是一个错误:https://github.com/thoughtbot/shoulda-matchers/issues/830

2 回答

  • 0

    您的变量目前仅为所有测试设置一次

    当您编写如下代码时:

    RSpec.describe User, type: :model do
      user = FactoryGirl.build(:user)
    end
    

    每次运行新规范时,您都不会构建新用户 . 同样,使用#let是错误的方法,因为it memoizes the variable甚至在测试之间 . 相反,您需要使用RSpec before#each块 . 例如:

    describe User do
      before do
        @user = FactoryGirl.build :user
      end
    
      # some specs
    end
    

    如果您有测试将用户持久化到数据库,并且如果您在测试之间禁用了回滚或数据库清理,那么您定义的工厂(如当前编写的)肯定会失败唯一性验证 . 在这种情况下,您可能想尝试:

    在测试中使用

    • User.delete_all ,或以其他方式在测试之间清理数据库 .

    • 使用FactoryGirl sequencesFaker gem确保用户属性实际上是唯一的 .

  • 0

    USE let

    RSpec.describe User, type: :model do
      let(:user) { FactoryGirl.build(:user) }
    
      # other what you need
    

相关问题