0

私は RSPEC でかなり頻繁に factory girl を使用してきましたが、今月はテスト スイートに Cucumber のストーリーを実装する任務を負っています。よくわからない問題が発生する可能性があると思います。

「メイン」アカウント モデルは「会社」と呼ばれます。ユーザー、従業員等がこれに属します。af/k を通じて直接行うものもあれば、委任を通じて行うものもあります。factory-girl を使用する私たちの古い方法では、Factory girl でビルドされたモデルのインスタンス変数を多数セットアップしました。

つまり、「spec_helper.rb」で

@grade_system = FactoryGirl.create(:grade_system)
@asset_size = FactoryGirl.create(:asset_size)
@asset_size.grades.create!(FactoryGirl.attributes_for(:grade))
@company = FactoryGirl.create(:company, :asset_size => @asset_size, :grade_system => @grade_system)

これはかなり愚かなIMOでした。

「属性が既に定義されています: 関連付け」という適切な関連付けでファクトリを修正しようとすると、エラーが発生し続けます。従業員に属するファクトリーで作成されたユーザーが、両方とも関連付けられているファクトリーで構築されているため、競合が発生しているためだと思います。会社。しかし、これは唯一の例ではありません。私の質問は、この状況のベストプラクティスは何かということだと思います。会社をスタブアウトして、それを必要とするすべてのファクトリーに割り当てることができれば、うまくいくかもしれませんし、適切なアソシエーションをすべて会社のファクトリーに詰め込むことができれば、FactoryGirl でユーザーを構築することはできません。 .build(:ユーザー)。.... それとも、関連付けがどのように機能するかについての要点を見逃しているだけですか?

FactoryGirl.define do
  factory :company do

   sequence(:name)                    { |n|  "Company#{n}" }
   sequence(:subdomain)               { |n| "subdomain#{n}" }  
   first_time_setup                   false

   non_exempt_multiplier              1.2
   exempt_multiplier                  1.2
   executive_multiplier               1.2

   primary_contact_first_name         'Jarrett'
   primary_contact_last_name          'Green'
   primary_contact_email              'tes@test.com'
   primary_contact_phone              '(555) 555-5555'
   hours_considered_part_time         30
   hours_considered_full_time         40

   association :industry
   association :grade_system
   association :asset_size

 end
end

######################################

FactoryGirl.define do
  require 'faker'
  factory :employee do

    association :company
    association :position
    association :branch

    first_name                Faker::Name.first_name
    last_name                 'Smith'
    pay_basis                 'salary'
    current_salary            10000.00
    date_in_position          (Date.today)
    sequence(:internal_id)    { |n| n }  

    user
  end
end

############################################################

FactoryGirl.define do
  factory :user do
    association :company 
    sequence(:login)          {|l|  "user#{l}@test.com"}
    sequence(:first_name)     {|fn| "UserFirstName#{fn}"}
    sequence(:last_name)      {|ln| "UserLastName#{ln}"}
    password                  'thisisthepassword'
    password_confirmation     'thisisthepassword'
  end
end
4

1 に答える 1

1

これに対処するための興味深いアプローチは、Fixtures を親レコードとして使用し、それらをファクトリで定義することです。モデルごとに 1 つの有効なフィクスチャを作成し、次のようにファクトリ定義で割り当てることができます。

association : grade_system { GradeSystem.find(12345678) }

ここで、数字はフィクスチャの ID です。

このアプローチには、いくつかの優れた点があります。まず、子を作成するたびに親レコードを作成する必要がないため、高速です。フィクスチャはテスト実行の開始時に一度ロードされ、最後まで保持されます。次に簡単です。各フィクスチャにはid、フィクスチャの名前に基づいて番号が付けられます。すべての実行で常に同じであるため、find直接使用するだけで安心できます。また、関連付けを簡単にリンクできるため、作成する必要はありません。工場を建てるときの両親の両親。3 番目に柔軟性があり、ファクトリが作成または構築されたときにテストする必要がある場合は、いつでも別の親を渡すことができます。

親として使用する各タイプを 1 つだけ作成するため、フィクスチャに関するほとんどの問題を回避できます。

于 2012-09-18T12:59:28.490 に答える