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

时间:2011-10-26 19:21:23

标签: ruby-on-rails module mixins factory-bot

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

Helper模块(在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::Helpersdefine之前,definefactory :user之间以及factory :user之内
  • spec_helper.rb中,我已经拥有以下内容:config.include Tests::Helpers并且可以让我访问我的规范中的random_string
  • 只需要我工厂的文件

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

3 个答案:

答案 0 :(得分:10)

仅仅是:

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

答案 1 :(得分:6)

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

答案 2 :(得分:4)

我昨天(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