FactoryGirl创建返回值(_C)



根据我的理解,工厂的"to_create"方法的返回值被忽略。这意味着从工厂的"build"或"initialize_with"部分返回的对象是在测试中调用"create"时最终返回的对象。

在我的案例中,我使用的是Repository模式的一个变体。我正在重写工厂的"to_create"部分,以包括对存储库"save"方法的调用。此方法不修改给定的对象,而是返回一个表示原始对象的持久化形式的对象。

但是,从"build"块返回的实例是从工厂返回的,而不是在"to_create"块中创建的实例。在我的代码中,这意味着返回对象的"不受约束"形式,而不是保存操作中具有更新属性(例如"id")的对象。

是否有一种方法可以强制"create"的返回值是"to_create"块的结果或该块中生成的某个值?

class Foo
  attr_accessor :id, :name
  ...
end
class FooRepository
  def self.create(name)
    Foo.new(name) # this object is not yet persisted and has no .id
  end
  def self.save(foo)
    # this method must not guarantee that the original Foo instance
    # will always be returned
    ...
    updated_foo # this is a duplicate of the original object
  end
  ...
end
FactoryGirl.define do
  factory :foo, class: FooRepository do
    # create an example Foo
    initialize_with { FooRepository.create(name: "Example") }
    # save the Foo to the datastore, returning what may be a duplicate
    to_create {|instance| FooRepository.save(instance)}
  end
end
describe FooRepository do
  it "saves the given Foo to the datastore" do
    foo = create(:foo)
    foo.id #=> nil
    ...
  end
end

除了"提出问题"之外,我没有其他答案,对不起。

默认的创建回调如下所示:

$ grep to_create lib/factory_girl/configuration.rb
to_create {|instance| instance.save! }

主要问题是,当你在ActiveRecord上调用save!时,它会在适当的位置修改自己。FactoryGirrl会忽略从to_create返回的任何新对象。

如果你想覆盖默认的创建策略,一个快速破解:

module FactoryGirl
  module Strategy
    class Create
      def association(runner)
        runner.run
      end
      def result(evaluation)
        evaluation.object.tap do |instance|
          evaluation.notify(:after_build, instance)
          evaluation.notify(:before_create, instance)
          instance = evaluation.create(instance) # <-- HACK
          evaluation.notify(:after_create, instance)
        end
      end
    end
  end
end

或者对您的to_create挂钩进行此操作,以模仿Rails的就地修改:

to_create do |record|
  new_record = YourRepositoryHere.new.create(record)
  record.attributes = new_record.attributes # For example
  new_record # Return the record just in case the bug is fixed
end

祝你好运(

最新更新