web-dev-qa-db-ja.com

名前空間モデルでRspecでfactory_girl_Railsを使用する

いくつかの異なるクライアントに広告を配信するWebサービスがあります。広告の構造はクライアントによって異なるため、モデルとコントローラーの名前空間をクライアント名で使用して、広告を区別しています。高レベルから見ると、次のようになります。

'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-Rails2.4.0とfactory_girl_Rails1.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

それは仕事をしませんでした。私は周りを見回しましたが、私が見たすべての例は、名前空間のないモデルを使用していました。誰かアイデアはありますか?どんな入力でも大歓迎です。

35
Simon Bagreev

ここに最小限の実例があります。問題がどこにあるかを特定するために使用できるかもしれません。 dmarkowの回答に残したコメントは、どこか別の場所にエラーがあることを示唆しています。

app/models/bar/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

spec/factorys.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

それが役に立てば幸い。

49
Jorge Gajon

この回答が投稿されてから、FactoryGirlが変わったのではないかと思います。私はそれを機能させるためにやった

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

FactoryGirl4.5.)の現在の最新バージョンでは、次の構文が使用されます。

FactoryGirl.define do
  factory :client1_ad, class: Client1::Ad do |f|
    f.title       "software tester"
    f.description "Immediate opening"
  end
end

client1_adは、任意の名前にすることができます。cozは、すでにそのクラス名を識別します。

8
Hoang Le

私はこの質問がFactoryGirlに関連する問題を調べているのを見つけ、ソースを少し読んだ後、工場の名前を変更することで問題を解決できることがわかりました。

モジュール内で名前空間が付けられたモデルクラスがある場合、例:_Admin::User_次のようにファクトリを定義する必要がありました。

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

のではなく:

_factory :admin_user, class: Admin::User do
  #...
end
_

たぶん、このちょっとした情報がいつか誰かを助けるかもしれません。私の問題の詳細は、build(described_class)を使用してRSpec仕様のファクトリからインスタンスを構築しようとしたことでした。これは、名前空間のないクラスでは問題なく機能しますが、モジュール内のクラスでは機能しません。その理由は、ファクトリを検索するときに、FactoryGirlがActiveSupportunderscoreヘルパーを使用してファクトリ名を正規化するためです。

1
orj

クラス名の文字列ではなく、実際のクラスを渡してみましたか?

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