【问题标题】:FactoryBot factory with static attributes具有静态属性的 FactoryBot 工厂
【发布时间】:2019-01-13 17:33:47
【问题描述】:

我想为 XML 序列化创建一个集成测试,它从数据库中检索数据,然后创建 XML 文件。 我需要一些具有静态属性的工厂,即它们始终具有相同的值,以允许对生成的 XML 设置期望。

例如,在我的User 工厂中,我有:

  factory :static_user, class: User do
    id { '78474912-7728-4478-8810-151a1347d546' }
    role { :admin }
    email { 'john.root@mail.com' }
    password { 'password' }
    password_confirmation { 'password' }
    created_at { Time.parse 'Wed, 26 Sep 2018 11:06:59 UTC +00:00' }
    updated_at { Time.parse 'Wed, 26 Sep 2018 11:06:59 UTC +00:00' }
  end

虽然当我尝试在另一个工厂中使用它作为关联时,我需要使用自定义初始化来包装它:

FactoryBot.define do
  factory :static_order, class: Order do
    association :user, factory: :static_user do
      initialize_with { User.find_or_initialize_by(build(:static_user)) }
    end
  end
end

我怎样才能避免这种情况?

我可以在每次测试之前使用DatabaseCleaner gem 将数据库清空,但如果我尝试创建项目列表,我会收到重复属性(具有唯一验证)的错误。

【问题讨论】:

  • 使用固定值实际上只是意味着您将工厂用作固定装置。不用写expect(foo.bar).to eq 'baz',你可以写expect(foo.bar).to eq factory_instance.bar,这意味着你不再有规范和工厂之间的紧密耦合,这是一件好事。
  • 如果id是静态的,为什么不设置user_id而不是user呢?使用与静态用户 ID 相同的固定字符串

标签: ruby-on-rails ruby factory-bot


【解决方案1】:

恐怕为每个create(:static_order) 创建一个新的User 是理想的行为。

在工厂中设置id 会在创建多个用户时中断。您可以改用序列,或者在实例化用户时自己设置 id,这样您仍然可以控制 id。如果您希望您的订单共享同一个用户,则需要显式传递它们。

let(:user) { create(:user, id: '78474912-7728-4478-8810-151a1347d546') }
let!(:order1) { create(:static_order, user: user) }
let!(:order2) { create(:static_order, user: user) }

【讨论】:

    【解决方案2】:

    使用@max 引用,我最终会使用有意义的固定装置,因为它们可以在事务中运行并提供静态值。

    所以我发布了这个,好像有人试图遵循同样的建议,但方向错误,因为这是固定装置的用途。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多