Factory Girl的额外参数

22

我需要向Factory Girl传递额外的参数,以便在回调函数中使用。就像这样(但实际上更复杂):

Factory.define :blog do |blog|
  blog.name "Blah"

  blog.after_create do |blog|
    blog.posts += sample_posts
    blog.save!
  end
end

然后使用类似以下方式创建它:

Factory.create(:blog, :sample_posts => [post1, post2])

你有什么想法如何做到这一点吗?

5个回答

32
这现在可以通过瞬态属性而不需要任何“hack”来实现(请参见问题#49评论中的说明)。
例子:
FactoryGirl.define do
  factory :user do
    transient do
      bar_extension false
    end
    name {"foo #{' bar' if bar_extension}"}
  end
end

# Factory(:user).name = "foo"
# Factory(:user, :bar_extension => true).name = "foo bar"

对于 Factory Girl 版本低于 5.0:

FactoryGirl.define do
  factory :user do
    ignore do
      bar_extension false
    end
    name {"foo #{' bar' if bar_extension}"}
  end
end

# Factory(:user).name = "foo"
# Factory(:user, :bar_extension => true).name = "foo bar"

3
这些文档非常有用,包括如何在 after_create 或其他块中访问瞬态属性的说明:https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md - Hollownest

2

一种选择是为额外的帖子创建虚拟访问器,供after_create钩子检查:

class Blog
  has_many :posts
  attr_accessible :name, :title, ... # DB columns
  attr_accessor   :sample_posts      # virtual column
end

Factory.define :blog do |blog|
  blog.name 'Blah'

  blog.after_create do |b|
    b.posts += b.sample_posts
    b.save!
  end
end

Factory(:blog, :sample_posts => [post1, post2])

对于我的示例,这将起作用,但我的实际情况有点更复杂。此外,我不想为了FactoryGirl的限制而污染模型。无论如何,谢谢 :) - pupeno
1
你只需要在test环境中污染模型即可。实际上,你可以直接在factories.rb中完成。 - James A. Rosen

2

问题#49最近已经关闭,请查看我的答案 - wintersolutions

1
如果你正在factorygirl文件中打开类,我建议这样做:
require "user"
class User
  attr :post_count
end

因此,您是在打开类,而不是覆盖它。


1
另一个选择是使用build而不是create,并将:autosave添加到集合中:
class Blog
  has_many :posts, :autosave => true
end

Factory.define :blog do |blog|
  blog.name 'Blah'
  blog.posts { |_| [Factory.build(:post)] }
end

Factory(:blog, :posts => [post1, post2])
#or
Factory.build(:blog, :posts => [unsavedPost1, unsavedPost2])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接