Factory Bot生成数据错误,Rails项目自赞校验单元测试未按预期触发原因排查
问题分析
该问题既不是Rails框架逻辑缺陷,也不是Factory Bot的bug,完全由工厂配置错误、测试场景预设不匹配导致。
核心错误点1:测试场景不符合自赞校验触发条件
当前Factory Bot配置生成Vote实例时,会创建两个完全独立的用户对象:
- Vote关联的
user属性对应一个独立生成的用户 - Votable关联的Question实例,其
author属性对应另一个独立生成的用户
Factory默认每次调用同名工厂都会生成新实例,因此两个用户ID永远不相等,votable.author_id == user_id的判断条件永远不成立,校验逻辑不会触发,errors信息中自然不存在self-like报错,和测试期望完全不匹配。
核心错误点2:build方法的关联属性行为符合预期
你提到打印pp vote时外键属性全为nil,属于Factory Bot build方法的正常表现:
对于belongs_to类型关联,默认使用build方法实例化主对象时,只会在内存中初始化关联对象,不会给主对象的外键字段(user_id、votable_id、votable_type)赋值。只有调用create方法持久化主对象,或者显式访问关联对象触发加载后,外键字段才会被赋值,这就是你单独调用pp vote.votable可以正常拿到对象的原因。
修复方案
步骤1:修改Factory配置,新增自赞场景的专用trait
FactoryBot.define do factory :vote do value { 1 } user association :votable, factory: :question # 自赞场景:投票用户和内容作者为同一人 trait :self_like do after(:build) do |vote| vote.votable.author = vote.user end end end end
步骤2:调整测试用例,使用对应trait构造测试对象
describe 'validate :self_like' do let(:vote) { build :vote, :self_like } it "adds error when user votes for their own content" do vote.valid? expect(vote.errors[:user]).to include('self-like') end end
内容的提问来源于stack exchange,提问作者noobie
相关产品推荐
相关产品推荐

