#ruby-on-rails #module #mixins #factory-bot
#ruby-on-rails #модуль #миксины #factory-бот
Вопрос:
Я пытаюсь повторно использовать вспомогательный метод на всех своих фабриках, однако я не могу заставить его работать. Вот моя настройка:
Вспомогательный модуль (в 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
, междуdefine
иfactory :user
и внутриfactory :user
) - у
spec_helper.rb
меня уже есть следующее:config.include Tests::Helpers
и это дает мне доступ кrandom_string
моим спецификациям - просто требуется файл на моей фабрике
Я также безуспешно прочитал следующие ссылки:
Ответ №1:
Как насчет простого:
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. Это работает так, но я надеялся, что мне не придется писать все пространство имен. Я оставлю вопрос открытым на случай, если кто-то найдет лучший способ.
2. Это работает, хотя я закончил, оставив свой вспомогательный модуль таким, какой он есть (с использованием метода экземпляра) и включив этот модуль в
DefinitionProxy
класс. Большое спасибо!3. Важно отметить: мой
rand
метод не работал как есть, и мне пришлось заменить егоKernel.rand
на из-за некоторого конфликта с FactoryGirl.
Ответ №2:
ответ 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
Комментарии:
1. Выглядит намного проще, я попробую, когда у меня будет время.
2. FG v4 больше не использует ::Proxy — fwiw, вы получите тот же эффект, заменив
FactoryGirl::Proxy.send
в ответе @FactoryGirl::SyntaxRunner.send
cuvius на, но обратите внимание, что разработчик gem думает о правильном решении в самом gem , поэтому следите за этими событиями, если вы делаете это.
Ответ №3:
Вчера я тестировал другие ответы (24.04.2012) и … ни один из них на самом деле не работает.
Похоже, что 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