如何让 FactoryBot return 成为正确的 STI sub class?
How to make FactoryBot return the right STI sub class?
我正在对系统进行重大更改,因此我将其中一个主表更改为 STI,并创建子类来实现特定行为。
class MainProcess < ApplicationRecord
end
class ProcessA < MainProcess
end
class ProcessB < MainProcess
end
在应用程序代码中,如果我 运行 MainProcess.new(type: 'ProcessA')
它会 return 我想要的 ProcessA 。
但是在 Rspec 测试中,当我 运行 FactoryBot::create(:main_process, type: 'ProcessA')
它正在 returning a MainProcess 并破坏我的测试。
我的因素是这样的
FactoryBot.define do
factory :main_process do
foo { 'bar' }
end
factory :process_a, parent: :main_process, class: 'ProcessA' do
end
factory :process_b, parent: :main_process, class: 'ProcessB' do
end
end
有没有办法让 FactoryBot 具有与普通程序相同的行为?
我找到了解决方案
FactoryBot.define do
factory :main_process do
initialize_with do
klass = type.constantize
klass.new(attributes)
end
end
...
end
答案在这里http://indigolain.hatenablog.com/entry/defining-factory-for-sti-defined-model(日语)
⚠⚠⚠重要⚠⚠⚠
如前所述 initialize_with
是私有 FactoryBot 的一部分 API。
根据 documentation:
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
所以尽量避免使用。 (虽然我没有找到任何其他方法来实现这个结果而不使用它)
如果您只是修改原始代码以将 class 指定为 class 类型而不是字符串,它会起作用:
FactoryBot.define do
factory :main_process do
foo { 'bar' }
end
factory :process_a, parent: :main_process, class: ProcessA do
end
factory :process_b, parent: :main_process, class: ProcessB do
end
end
initialize_with
被标记为 FactoryBot 私有 API 的一部分,不建议外部使用。
我想你可以使用嵌套工厂来完成这个。
factory :process do
factory :type_a_process, class: Process::TypeA do
type {"Process::TypeA"}
end
factory :type_b_process, class: Process::TypeB do
type {"Process::TypeB"}
end
end
end
FactoryBot.create(:type_b_process)
我正在对系统进行重大更改,因此我将其中一个主表更改为 STI,并创建子类来实现特定行为。
class MainProcess < ApplicationRecord
end
class ProcessA < MainProcess
end
class ProcessB < MainProcess
end
在应用程序代码中,如果我 运行 MainProcess.new(type: 'ProcessA')
它会 return 我想要的 ProcessA 。
但是在 Rspec 测试中,当我 运行 FactoryBot::create(:main_process, type: 'ProcessA')
它正在 returning a MainProcess 并破坏我的测试。
我的因素是这样的
FactoryBot.define do
factory :main_process do
foo { 'bar' }
end
factory :process_a, parent: :main_process, class: 'ProcessA' do
end
factory :process_b, parent: :main_process, class: 'ProcessB' do
end
end
有没有办法让 FactoryBot 具有与普通程序相同的行为?
我找到了解决方案
FactoryBot.define do
factory :main_process do
initialize_with do
klass = type.constantize
klass.new(attributes)
end
end
...
end
答案在这里http://indigolain.hatenablog.com/entry/defining-factory-for-sti-defined-model(日语)
⚠⚠⚠重要⚠⚠⚠
如前所述 initialize_with
是私有 FactoryBot 的一部分 API。
根据 documentation:
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
所以尽量避免使用。 (虽然我没有找到任何其他方法来实现这个结果而不使用它)
如果您只是修改原始代码以将 class 指定为 class 类型而不是字符串,它会起作用:
FactoryBot.define do
factory :main_process do
foo { 'bar' }
end
factory :process_a, parent: :main_process, class: ProcessA do
end
factory :process_b, parent: :main_process, class: ProcessB do
end
end
initialize_with
被标记为 FactoryBot 私有 API 的一部分,不建议外部使用。
我想你可以使用嵌套工厂来完成这个。
factory :process do
factory :type_a_process, class: Process::TypeA do
type {"Process::TypeA"}
end
factory :type_b_process, class: Process::TypeB do
type {"Process::TypeB"}
end
end
end
FactoryBot.create(:type_b_process)