Rails工厂女孩协会

时间:2012-08-10 17:45:53

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

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

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

工厂女孩 - 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工厂中生成的相同安全性。此代码目前创建两个单独的证券,因此中立位置与一个证券相关联,而头寸工厂则与不同的证券相关联。

我怎样才能做到这一点?我在整个应用程序中都看到了这个问题,所以搞清楚这一点会大大改善我的应用程序测试套件并保持代码干净。

2 个答案:

答案 0 :(得分:1)

实际上,您可以更轻松地在测试/规格中对此进行排序,而不是工厂定义。

首先创建一个安全性并将其分配给变量。

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

虽然您的示例有点复杂,但可能如下所示:

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

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

答案 1 :(得分: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