Validates_Associated 的简单规范

Simple Spec That Validates_Associated

我正在尝试对我的 Campaign 模型进行验证。我有一个允许用户 Create a Campaign 的表格,这应该要求他们在保存之前选择 program

我尝试按照 SO 上的一些答案进行操作,但无法使它们起作用。这是我目前所拥有的..

关系..

class Campaign < ActiveRecord::Base
    belongs_to :program
    validates_associated :program, 
        message: "You need to choose a Program."
end

class Program < ActiveRecord::Base
    has_many :campaigns
end

..和规范

it 'validates associated campaign' do
  campaign = build(:campaign)
  expect(campaign.save).to be false
  expect(campaign.errors).to eq "You need to choose a Program."
end

失败..

Failures:

  1) Campaign validates associated campaign
     Failure/Error: expect(campaign.save).to be false

       expected false
            got true
     # ./spec/models/campaign_spec.rb:34:in `block (2 levels) in <top (required)>'

validates_associated 仅在关联对象存在时有效。在您的示例规范中,活动工厂(我假设)没有添加关联程序,因此没有执行验证,活动被保存。

您要查找的是 validates :program, presence: true,如果缺少该程序,valid? 将 return 为 false。

Rails Guide for ActiveRecord Validations 中查看更多信息。

缺少 validates_associated 的内置匹配器,我这样写:

it { is_expected.not_to validate_presence_of(:program) }

context 'when program is present' do
  let(:program) { FactoryBot.create(:program) }
  before { subject.program = program }
  it { is_expected.to be_valid }

  context 'when program is present but not valid' do
    before { program.owner = nil }
    it { is_expected.not_to be_valid }
  end
end

这一行:before { program.owner = nil } 需要一些程序验证方面的知识。从 Campaign 的单元测试的上下文来看,这并不理想,但这并不是我犯过的最糟糕的编程错误。