I want to test following controller with RSpec
coupons_controller.rb:
class Api::V1::CouponsController < ApiController
def index
if params[:profile_id]
@coupons = Profile.find(params[:profile_id]).coupons
end
end
end
I want to know
1) How to create factories with FactoryBot
(spec/factories/profiles.rb
, coupons.rb
, coupon_profiles.rb
)
2)How to write spec/controllers/coupons_controllers.rb
:
profile.rb
class Profile < ApplicationRecord
accepts_nested_attributes_for :coupon_profiles
end
coupon.rb
class Coupon < ApplicationRecord
has_many :coupon_profiles
end
coupon_profile.rb
class CouponProfile < ApplicationRecord
belongs_to :coupon
belongs_to :profile
end
Something like:
# 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
Honestly, your best bet is reviewing the GETTING_STARTED README for FactoryBot -- everything you want to know is in there, with examples. It is a shining example of a README. (Note on the use of class
in my example above, there are specific performance reasons to use the stringified class name instead of the class constant)
For your controller specs, have you reviewed the RSpec Documentation? Though it's recommended that you use more functional testing like Request specs instead of controller specs. You should be able to do something like:
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