如何在factory_girl工厂中包含一个模块?

我正在尝试在我的所有工厂中重用一个辅助方法,但是我无法让它工作。 这是我的设置:

辅助模块(在spec / support / test_helpers.rb中)

module Tests module Helpers # not guaranteed to be unique, useful for generating passwords def random_string(length = 20) chars = ['A'..'Z', 'a'..'z', '0'..'9'].map{|r|r.to_a}.flatten (0...length).map{ chars[rand(chars.size)] }.join end end end 

工厂(在spec / factories / users.rb中)

 FactoryGirl.define do factory :user do sequence(:username) { |n| "username-#{n}" } password random_string password_confirmation { |u| u.password } end end 

如果我运行我的测试(使用rake spec ),无论在哪里创建具有Factory(:user)的用户,我都会收到以下错误:

  Failure/Error: Factory(:user) ArgumentError: Not registered: random_string 

为了能够在我的工厂中使用random_string ,我该怎么办?

我尝试过以下方法:

  • 在我的工厂的每个级别使用include Tests::Helpers (在define之前,在definefactory :user之间factory :user和内部factory :user
  • spec_helper.rb ,我已经拥有以下内容: config.include Tests::Helpers ,它让我可以访问我的规范中的random_string
  • 只需要我工厂的文件

我还阅读了以下链接但没有成功:

  • 在模块中定义辅助方法
  • RSpec中代码重用的不同方式

仅仅是:

 module Tests module Helpers # not guaranteed to be unique, useful for generating passwords def self.random_string(length = 20) chars = ['A'..'Z', 'a'..'z', '0'..'9'].map{|r|r.to_a}.flatten (0...length).map{ chars[rand(chars.size)] }.join end end end 

然后:

 FactoryGirl.define do factory :user do sequence(:username) { |n| "username-#{n}" } password Tests::Helpers.random_string password_confirmation { |u| u.password } end end 

好的,明白了:)请执行以下操作:

 module FactoryGirl class DefinitionProxy def random_string #your code here end end end 

apneadiving的答案对我不起作用。 我必须做以下事情:

 # /spec/support/factory_helpers.rb module FactoryHelpers def my_helper_method # ... end end FactoryGirl::Proxy.send(:include, FactoryHelpers) 

然后你可以使用它如下:

 FactoryGirl.define do factory :post do title { my_helper_method } end end 

我昨天(2012年4月24日)测试了其他答案,并且……其中没有一个确实有效。

看起来像Factory Girl gem(v3.2.0)已经发生了很大的变化。

但我想出了一个快速的解决方案:

 # factories.rb module FactoryMacros def self.create_file(path) file = File.new(path) file.rewind return ActionDispatch::Http::UploadedFile.new(:tempfile => file, :filename => File.basename(file)) end end # also factories.rb FactoryGirl.define do factory :thing do |t| t.file { FactoryMacros::create_file("path-to-file") end end