7

我想在我的工厂中干掉创建/构建后的钩子:

FactoryGirl.define do

  factory :poll do

    sequence :title do |n|
      "MyPollTitle#{n}"
    end
    sequence :description do |n|
      "MyPollDescription#{n}"
    end
    user

    factory :poll_with_answers do

      ignore do
        answers_count 2
      end

      after(:build) do |poll, evaluator|
        evaluator.answers_count.times do
          poll.answers << build(:answer, poll: poll)
        end
      end

      after(:create) do |poll, evaluator|
        evaluator.answers_count.times do
          poll.answers << create(:answer, poll: poll)
        end
      end
    end
  end
end

我面临的问题是我似乎无法在 FG 中定义方法?想法如何干燥?

4

2 回答 2

7

首先,after(:create)隐式调用after(:build),至少在最新版本的 FactoryGirl 中:

after(:build) - 在工厂建成后调用(通过 FactoryGirl.build、FactoryGirl.create)

https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#callbacks

因此,在您的情况下,以下代码就足够了:

after(:build) do |poll, evaluator|
  evaluator.answers_count.times do
    poll.answers << build(:answer, poll: poll)
  end
end

但是,当您使用而不是after(:build)时不会触发,这是我遇到此线程时尝试做的事情。要干掉这段代码,事实证明你可以使用该方法为多个方法调用同一个块:build_stubbed()build()callback()

factory :user do
  callback(:after_build, :after_stub) do |user|
    do_something_with(user)
  end
end
于 2014-02-25T19:14:30.920 回答
1

这可能是一个便宜的技巧,但您可以在第二个工厂中创建一个 lambda:

factory :poll_with_answers do
  ignore do
    answers_count 2
  end

  make_answers = lambda do |poll, evaluator, method|
    evaluator.answers_count.times do
      poll.answers << send(method, :answer, poll: poll)
    end
  end

  after(:build) do |poll, evaluator|
    make_answers.call poll, evaluator, :build
  end

  after(:create) do |poll, evaluator|
    make_answers.call poll, evaluator, :create
  end
end

我对这种模式一点也不满意,但至少它是干的。

于 2012-07-18T08:28:24.280 回答