Использование factory_girl_rails с Rspec для моделей с именами
У меня есть веб-сервис, который обслуживает рекламу нескольким различным клиентам. Структура объявления зависит от клиентов, и поэтому я использую пространства имен для своих моделей и контроллеров по имени клиента для различения рекламы. С высокого уровня он выглядит так:
'app/models/client1/ad.rb'
class Client1::Ad < ActiveRecord::Base
attr_accessible :title, :description
end
'app/models/client2/ad.rb'
class Client2::Ad < ActiveRecord::Base
attr_accessible :title, :description, :source
end
В действительности эти модели более сложны и имеют ассоциации, но это не главное.
Я пишу некоторые модульные тесты, используя rspec-rails 2.4.0 и factory_girl_rails 1.0.1, и все мои заводы работают отлично. Однако я не могу определить фабрики для моделей с именами. Я пробовал что-то вроде:
Factory.define :client1_ad, :class => Client1::Ad do |ad|
ad.title "software tester"
ad.description "Immediate opening"
end
и
Factory.define :client2_ad, :class => Client2::Ad do |ad|
ad.title "software tester"
ad.description "Immediate opening"
ad.source "feed"
end
Это не сработало. Я огляделся, но каждый пример, который я видел, использовал модели, не содержащие имен. У кого-нибудь есть идеи? Любые входные данные приветствуются.
Ответы
Ответ 1
У меня есть минимальный рабочий пример, возможно, вы можете использовать его, чтобы определить, где ваша проблема. Комментарий, который вы оставили в ответе dmarkow, подсказывает мне, что у вас есть ошибка где-то еще.
приложение/модели/бар/foo.rb
class Bar::Foo < ActiveRecord::Base
end
* дб/мигрировать/20110614204536_foo.rb *
class Foo < ActiveRecord::Migration
def self.up
create_table :foos do |t|
t.string :name
end
end
def self.down
drop_table :foos
end
end
спецификации/factories.rb
Factory.define :foo, :class => Bar::Foo do |f|
f.name 'Foooo'
end
* спецификация/модель/foo_spec.rb *
require 'spec_helper'
describe Bar::Foo do
it 'does foo' do
foo = Factory(:foo)
foo.name.should == 'Foooo'
end
end
Запуск теста:
$ rake db:migrate
$ rake db:test:prepare
$ rspec spec/models/foo_spec.rb
.
Finished in 0.00977 seconds
1 example, 0 failures
Надеюсь, что это поможет.
Ответ 2
Я думаю, возможно, FactoryGirl изменится, так как этот ответ был опубликован. Я сделал, чтобы он работал.
Factory.define do
factory :foo, :class => Bar::Foo do |f|
f.name 'Foooo'
end
end
Ответ 3
С текущей последней версией FactoryGirl
(4.5.0) это синтаксис:
FactoryGirl.define do
factory :client1_ad, class: Client1::Ad do |f|
f.title "software tester"
f.description "Immediate opening"
end
end
Обратите внимание, что client1_ad
может быть любым именем, которое вы хотите, потому что мы уже вынуждены идентифицировать его имя класса.
Ответ 4
Я нашел этот вопрос рассмотрев связанную с FactoryGirl проблему, и после небольшого чтения источника, который я понял, я мог решить свою проблему, переименовав свои заводы.
Когда у меня были классы моделей, которые были помещены во внутренние модули, например: Admin::User
, я должен был определять мои фабрики следующим образом:
factory :'admin/user', class: Admin::User do
#...
end
Вместо
factory :admin_user, class: Admin::User do
#...
end
Возможно, этот маленький лакомый кусочек информации может кому-то помочь кому-нибудь. Специфика моей проблемы заключалась в том, что я пытался использовать build(described_class)
для сборки экземпляров с фабрик в своих спецификациях RSpec
, и это отлично работает с классами, не поддерживающими имена, но не с классами внутри модулей. Причина в том, что при поиске фабрик FactoryGirl использует ActiveSupport
underscore
помощник для нормализации имени factory.
Ответ 5
Вы пробовали передать фактический класс, а не строку с именем класса:
Factory.define :client1_ad, :class => Client1::Ad do |ad|