FactoryBot - 如何传递瞬态数组?

FactoryBot - How can I pass a transient array?

我目前有一个 FactoryBot 特征设置如下:

trait :with_role do
  transient do
    role { nil }
  end

  after(:create) do |staff_member, factory|
    staff_member.staff_roles << StaffRole.fetch(factory.role) if factory.role
  end
end

但是,这个特性只允许工厂被传递一个单一的角色。我正在重构一系列测试,其中需要分配多个角色。这是一个 M-N 关系,由 DB 和 ORM 通过联结 table 支持,并且在 FactoryBot 之外显然按预期运行,因为原始测试实现通过了。我的做法是:

# Inside the factory
trait :with_roles do
  transient do
    roles { [] }
  end

  after(:create) do |staff_member, factory|
    roles.each { |role| staff_member.staff_roles << StaffRole.fetch(factory.send(role)) }
  end
end
# Invocation
staff_member = FactoryBot.create(:staff_member, :with_roles, roles: [
  :role_1,
  :role_2,
  :role_3
], some_other_attribute: 1)

问题是当我尝试以这种方式调用时,出现以下错误:

NameError: undefined local variable or method `roles' for #<FactoryBot::SyntaxRunner:...>

如果我将 roles 初始化为 nil 而不是空数组,我会得到完全相同的错误。以前的实现工作正常,我已经尽可能地遵循它。为什么 roles 尽管被定义为瞬态变量但仍未定义?我是否遗漏了有关 FactoryBot 工作原理的一些信息,并试图做一些不可能的事情?还是我只是想错了?

你应该给工厂打电话a transient attribute

after(:create) do |staff_member, factory|
  factory.roles.each { |role| staff_member.staff_roles << StaffRole.fetch(factory.send(role)) }
end