You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:24:10