11

私は FactoryGirl を初めて使用し、次の簡単なシナリオを試していますか?

factory :female, :class => Gender do
  code 'Female'
end

factory :male, :class => Gender do
  code 'Male'
end

factory :papas, :class => Customer do
  first_name 'Jim'
  last_name 'Papas'
  association :gender, :factory => :male, :strategy => :build
end

factory :dumas, :class => Customer do
  first_name 'Mary'
  last_name 'Dumas'
  association :gender, :factory => :female, :strategy => :build
end

次に、私のテストで:

 create(:male)
 create(:female)
 create(:papas)
 create(:dumas)

Customer クラスには関連付けbelongs_to Genderクラスと、それが存在する必要があることを示す検証規則があることに注意してgender_idください。Genderコードの一意性について、クラスの検証も行っています。

上記create(:papas)のステートメントで、私のテストでは、Customeris であるため、作成される予定の が無効であるというgender_idエラーが表示されnilます。

:strategy => :buildon factory の性別との関連付けを削除するCustomer :papasと、 を作成しようとすると:papas、性別のコードが既に存在するというエラーが表示されます。

上記のようにテストでデータを作成するには、何をする必要がありますか?

他のテストでも、顧客なしで性別を作成したいことに注意してください。factory create コマンドで顧客を作成し、同時に顧客に性別を作成させるように言わないでください。同じ性別の 2 人の顧客も作成しようとすると、これは機能しません。

また、次の回答よりも優れた回答が必要です。

@male = create(:male)
@female = create(:female)
create(:papas, :gender => @male)
create(:dumas, :gender => @female)

(フィクスチャを使用する場合、これらはそのまま使用できます。フィクスチャに戻りますか?)

4

3 に答える 3

14

Gender インスタンスにファクトリを使用せず、Customer ファクトリでコールバックを使用することで、目的を達成できます。

現状では、Gender ファクトリから多くを得ているわけではありません (ただし、この質問をするために単純化されている可能性があります)。これを同じように簡単に実行して、性別を取得できます。

Gender.find_or_create_by_code!('Male')

次に、Customer ファクトリで before コールバックを使用して Gender を設定できます。

factory :dumas, :class => Customer do
  first_name 'Mary'
  last_name 'Dumas'
  before_create do |customer|
    customer.gender = Gender.find_or_create_by_code!('Female')
  end
end

factory_girl でコールバックを使用するための形式が最近変更されたため、3.3 以降を使用している場合は、次のようにする必要があります。

before(:create) do |customer|

の代わりにbefore_create

性別の作成が例よりも複雑な場合でも、ファクトリを使用して性別を作成できますが、find_by_code!代わりにfind_or_create_by_code!.

于 2012-06-01T08:44:29.440 に答える
6

ignoreは推奨されておらず、Factory Girl のバージョン 5 で削除されます。

代わりに、一時的な属性を使用できます。

factory :dumas, :class => Customer do
  transient do
    female { Gender.find_by_code('Female') || create(:female) }
  end

  first_name 'Mary'
  last_name 'Dumas'
  gender { female }
end
于 2015-10-20T08:16:15.017 に答える
5

ignoreブロックを使用して、これをまとめることもできます。

factory :dumas, :class => Customer do
  ignore do
    female { Gender.find_by_code('Female') || create(:female) }
  end

  first_name 'Mary'
  last_name 'Dumas'
  gender { female }
end
于 2013-06-25T14:36:05.437 に答える