Использование factory_girl_rails с Rspec на моделях с пространством имен - PullRequest
35 голосов
/ 15 июня 2011

У меня есть веб-сервис, который обслуживает объявления для нескольких разных клиентов. Структура объявления варьируется в зависимости от клиента, и поэтому я использую пространства имен для своих моделей и контроллеров по имени клиента, чтобы различать объявления. С высокого уровня это выглядит так:

'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

Это не сделало работу. Я огляделся вокруг, но каждый пример, который я видел, использовал модели без пространства имен. У кого-нибудь есть идеи? Любой вклад приветствуется.

Ответы [ 5 ]

49 голосов
/ 15 июня 2011

У меня есть минимальный рабочий пример, возможно, вы могли бы использовать его, чтобы точно определить, где ваша проблема.Комментарий, который вы оставили в ответе dmarkow, подсказывает мне, что у вас есть ошибка в другом месте.

app / models / bar / foo.rb

class Bar::Foo < ActiveRecord::Base
end

* дБ/migrate/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

spec / фабрики.* Запуск теста:

$ rake db:migrate
$ rake db:test:prepare
$ rspec  spec/models/foo_spec.rb 
.

Finished in 0.00977 seconds
1 example, 0 failures

Надеюсь, это поможет.

12 голосов
/ 07 февраля 2014

Я думаю, что FactoryGirl изменится, так как этот ответ был опубликован.Я сделал, чтобы это заработало

Factory.define do
  factory :foo, :class => Bar::Foo do |f|
    f.name 'Foooo'
  end
end
8 голосов
/ 13 июля 2015

С текущей последней версией 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 может быть любым именем, которое вы хотите, потому что мы уже принудительно определяем его имя класса .

1 голос
/ 28 октября 2016

Я нашел этот вопрос, изучая связанную проблему с 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 для нормализации имени фабрики.

0 голосов
/ 15 июня 2011

Вы пытались передать фактический класс, а не строку с именем класса:

Factory.define :client1_ad, :class => Client1::Ad do |ad|
...