Rspec - 唯一性应该匹配失败

问题描述 投票:0回答:1

我有一个

ActiveRecord
表,其中有一列名为
name
。我需要这个字段存在并且是唯一的。所以我有以下规格

it { should validate_presence_of(:name) }
it { should validate_uniqueness_of(:name) }

模型中对应的规则为:

validates :name, presence: true, uniqueness: true

我的工厂包含以下内容:

FactoryBot.define do
  factory :model_name do
    sequence(:name) { |n| "Name #{n}" }

    after(:build) do |model|
      pack.rels << build(:relation)
    end
  end
end

问题是,当我运行规范时,出现以下错误。

Failure/Error: it { should validate_uniqueness_of(:name) }
     
     Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher::ExistingRecordInvalid:
       validate_uniqueness_of works by matching a new record against an
       existing record. If there is no existing record, it will create one
    Mysql2::Error: Field 'name' doesn't have a default value: INSERT INTO `table_name`

我做错了什么?

ruby-on-rails rspec shoulda
1个回答
0
投票

validate_uniqueness_of
匹配器与其他匹配相比,其行为有所不同,因为如果模型尚不存在,它会为模型创建一个实例。 文档中有一个警告部分,详细介绍了您的问题中描述的场景。

为了解决这个问题,您需要在测试范围内创建一个具有预填充字段的对象,以便您可以控制执行期间使用的属性值。

由于您使用的是 FactoryBot,您可以执行以下操作:

RSpec.describe ModelName, type: :model do
  describe "validations" do
    subject { FactoryBot.build(:model_name) }
    it { should validate_presence_of(:name) }
    it { should validate_uniqueness_of(:name) }
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.