Factory Bot如何根据属性覆写情况设置条件化属性值?
Factory Bot 工厂如何感知属性被覆写并动态调整
我至今没找到解决方案,只发现一个多年前的未解决问题。我的需求是:让Factory Bot工厂在调用create方法时,能根据被覆写的属性动态调整行为。
示例代码
class Contract < ApplicationRecord # 包含 start_date 和 end_date 属性 has_many :visits end class Visit < ApplicationRecord # 包含 date 属性 belongs_to :contract validates :date, within_period: true # 若 date < contract.start_date 或 date > contract.end_date 则抛出错误 end
Visit 工厂定义
FactoryBot.define do factory :visit do association :contract, start_date: Date.current, end_date: Date.current date { Date.current } end end
测试中的三种场景
# 场景1 create(:visit) # 创建成功,所有日期都是 Date.current,符合验证规则 # 场景2 create(:visit, date: '01/01/2001') # 创建失败,触发日期验证错误 # 场景3 create(:visit, contract: @contract) # 创建结果不确定,取决于 @contract 的日期属性是否和默认 date 匹配
期望的工厂行为
如果工厂能感知哪些属性被覆写:
- 场景2中:自动调整关联的contract的日期范围,让它包含覆写的date值
- 场景3中:自动将date设置为符合传入的contract验证规则的值(比如contract的start_date)
当前可选方案及顾虑
目前能想到的解决方式有两种:
- 测试时显式传入匹配的属性,比如
create(:visit, contract: @contract, date: @contract.start_date) - 使用traits定义不同的场景
但这两种方式都有顾虑:即使测试本身不关注日期验证规则,测试代码也必须了解这个规则才能写出合法的调用,感觉违反了测试的简洁性原则。
我目前打算采用第一种方案,让测试显式构建符合验证规则的对象,但想听听大家有没有相关的经验、尝试或者更好的建议。
内容的提问来源于stack exchange,提问作者vivipoit
相关产品推荐
相关产品推荐

