私の理解では、ファクトリの「to_create」メソッドからの戻り値は無視されます。これは、ファクトリの「build」または「initialize_with」部分から返されるオブジェクトが、テスト内で「create」を呼び出したときに最終的に返されるオブジェクトであることを意味します。
私の場合、リポジトリ パターンのバリアントを使用しています。ファクトリの「to_create」部分をオーバーライドして、リポジトリの「save」メソッドへの呼び出しを含めています。このメソッドは、指定されたオブジェクトを変更しませんが、オリジナルの永続化された形式を表すオブジェクトを返します。
ただし、「ビルド」ブロックから返されるインスタンスはファクトリから返され、「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