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

重写new方法的Rails ActiveRecord模型,如何用FactoryGirl定制测试主题?

问题与解决方案

问题背景

我有一个重写了new方法的Rails ActiveRecord模型Document,该方法需接收参数才能实例化包含必填字段的对象。在用Shoulda Matchers的RSpec模型测试中,我需要验证关联关系,目前只能通过直接传参实例化模型作为测试主题,想改用FactoryGirl工厂生成带定制参数的测试主题。

相关信息

模型代码

class Document < ApplicationRecord
  has_many :folders, dependent: :destroy
  belongs_to :project
  belongs_to :author, class_name: 'User'
end

当前测试代码

require 'spec_helper'

describe Document do
   describe 'associations' do
    it { should have_many(:folders).dependent(:destroy) }
    it { should belong_to(:project) }
    it { should belong_to(:author).class_name('User') }
  end
end

技术栈

  • Ubuntu 22.04.2 LTS
  • Rails 5.2.2
  • RSpec 3.8.0
  • Shoulda-matchers 3.1.3
  • FactoryGirl 4.9.0

解决方案

1. 定义Document工厂

在spec/factories/documents.rb中创建工厂,利用initialize_with调用重写后的new方法,传入必填参数:

FactoryGirl.define do
  factory :document do
    project { create(:project) }
    author { create(:user) }
    # 补充其他必填字段

    initialize_with { new(project: project, author: author) }
  end
end

注意:需确保project和user的工厂已存在,若没有需先创建对应工厂文件。

2. 修改RSpec测试使用工厂

更新测试代码,指定测试主题为工厂生成的实例:

require 'spec_helper'

describe Document do
  subject { build(:document) }

  describe 'associations' do
    it { should have_many(:folders).dependent(:destroy) }
    it { should belong_to(:project) }
    it { should belong_to(:author).class_name('User') }
  end
end

额外说明

  • 若重写的new方法需要更多定制参数,可在工厂中添加对应属性并传入initialize_with;
  • 使用build而非create是因为关联测试无需持久化对象,能提高测试效率;
  • 如需临时调整属性,可通过build(:document, author: create(:admin_user))传入定制参数。

内容的提问来源于stack exchange,提问作者Anas Shahid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:33:30