Factorybot でnested_attributes を持つモデルのファクトリを作成する方法
概要
RSpecで以下のコントローラーをテストしたい
クーポン_コントローラー.rb:
class Api::V1::CouponsController < ApiController
def index
if params[:profile_id]
@coupons = Profile.find(params[:profile_id]).coupons
end
end
end
私は知りたいです
- FactoryBot でファクトリーを作成する方法 (spec/factories/profiles.rb、クーポン.rb、クーポン_プロファイル.rb)
2)spec/controllers/coupons_controllers.rbの書き方:
プロフィール.rb
class Profile < ApplicationRecord
accepts_nested_attributes_for :coupon_profiles
end
クーポン.rb
class Coupon < ApplicationRecord
has_many :coupon_profiles
end
クーポン_プロフィール.rb
class CouponProfile < ApplicationRecord
belongs_to :coupon
belongs_to :profile
end
解決策
何かのようなもの:
# spec/factories/profiles.rb
FactoryBot.define do
factory :profile, class: 'Profile', do
# ...
end
end
# spec/factories/coupons.rb
FactoryBot.define do
factory :coupon, class: 'Coupon' do
# ...
end
end
# spec/factories/coupon_profiles.rb
FactoryBot.define do
factory :coupon_profile, class: 'CouponProfile' do
coupon
profile
end
end
正直に言うと、FactoryBot の GETTING_STARTED README を確認するのが最善の策です。知りたいことはすべてそこに例とともに記載されています。これは README の優れた例です。 (上記の例でのクラスの使用については、クラス定数の代わりに文字列化されたクラス名を使用する特定のパフォーマンス上の理由があることに注意してください)
コントローラーの仕様については、RSpec ドキュメントを確認しましたか?ただし、コントローラーの仕様ではなく、要求仕様などのより機能的なテストを使用することをお勧めします。次のようなことができるはずです:
describe 'coupons' do
subject { response }
shared_examples_for 'success' do
before { request }
it { should have_http_status(:success) }
end
describe 'GET /coupons' do
let(:request) { get coupons_path }
it_behaves_like 'success'
end
describe 'GET /coupons/:profile_id' do
let(:request) { get coupon_path(profile)
let(:profile) { coupon_profile.profile }
let(:coupon_profile) { create :coupon_profile }
it_behaves_like 'success'
end
end