Использование 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

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

5 ответов


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

app / модели / Бар / foo.rb

class Bar::Foo < ActiveRecord::Base
end

* db/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

спец/заводы.rb

Factory.define :foo, :class => Bar::Foo do |f|
  f.name 'Foooo'
end

* spec / models / 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

надеюсь, что это помогает.


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

Factory.define do
  factory :foo, :class => Bar::Foo do |f|
    f.name 'Foooo'
  end
end

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


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

когда у меня были классы моделей, которые были пространствами имен внутри модулей, например:Admin::User Я должен был определить свои фабрики так:

factory :'admin/user', class: Admin::User do
  #...
end

вместо:

factory :admin_user, class: Admin::User do
  #...
end

может, этот маленький лакомый кусочек информации может помочь кому-нибудь. Специфика моей проблемы заключалась в том, что я попытка использовать build(described_class) для создания экземпляров с заводов в my RSpec спецификации, и это отлично работает с классами без пространства имен, но не с классами внутри модулей. Причина в том, что внутренне при поиске заводов FactoryGirl будет использовать ActiveSupport ' s underscore хелпер для того чтобы нормализовать имя фабрики.


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

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