0

我正在尝试使用 Factory Girl 与我的工厂创建关联,以便关联对象共享正确的数据以将它们匹配在一起。

当我希望它们都与对象 C 的同一个实例相关时,我遇到了对象 A 与对象 C 的一个实例相关而对象 B 与对象 C 的另一个实例相关的场景。

Factory Girl - https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md 使用最新版本

这是我在项目中尝试做的一个简化示例。

FactoryGirl.define do
        factory :neutral_position, class: FinancialAccounting::Update::Neutral::Position do
          created_at    { Time.now }
          updated_at    { Time.now }

          factory :valid_neutral_position do
            association :security, factory: :security

            factory :valid_neutral_position_with_production_record do
              association :position, factory: :position

              # This modifies the created production account record so the attributes match.
              FactoryGirl.modify do
                factory :position, class: FinancialAccounting::Position do
                  association :security, factory: :security
                end
              end
            end
          end

        end
      end

请注意,我正在尝试修改关联的位置,以便它指向在 :valid_neutral_position 工厂中生成的相同安全性。此代码当前创建了两种独立的证券,因此中立头寸与一种证券相关联,而头寸工厂与另一种证券相关联。

我怎样才能做到这一点?我在整个应用程序中都看到了这个问题,因此解决这个问题将极大地改进我的应用程序测试套件并保持我的代码干燥。

4

2 回答 2

1

实际上,在您的测试/规范中而不是工厂定义中更容易解决这个问题。

首先创建一个证券并将其分配给一个变量。

然后,在创建要依赖该安全性的对象时,将变量传递给工厂构造函数。

尽管您的示例有点复杂,但它可能如下所示:

specific_security = FactoryGirl.create(:security)
valid_natural_position = FactoryGirl.create(:valid_natural_position, security: specific_security)
position = FactoryGirl.create(:position, security: specific_security)

通过这种方式,您可以确保在测试中以您需要的方式设置对象关系。它的另一个好处是减少了创建的对象数量,因为两个二级工厂将不再自动创建安全对象。

于 2012-08-14T13:41:10.107 回答
1

我实际上采用了不同的方法。它包含在工厂中,从而导致更清洁的测试。但是,我确实看到了在您不一定需要时必须生成更多对象的不利之处。

FactoryGirl.define do
  factory :neutral_position, class: FinancialAccounting::Update::Neutral::Position do
    created_at    { Time.now }
    updated_at    { Time.now }

    factory :valid_neutral_position do
      has_production_position
    end

    trait :has_production_position do
      association :position, factory: :position
      security { position.security }
    end

  end
end
于 2012-08-15T01:16:18.550 回答