I have abstracted out my models to be able to test multiple models at the same time. The issue is that some of the models have different parameters. Take this sample schema below.
Schemas (simplified)
# Table name: cars
#
# id :integer not null, primary key
# hp :integer
# wheels :integer
# Table name: trucks
#
# id :integer not null, primary key
# hp :integer
# wheels :integer
# Table name: boats
#
# id :integer not null, primary key
# motors :integer
# hp :integer
Test
setup do
@models = ['cars', 'trucks', 'boats']
end
test 'something awesome' do
@models.each do |model|
# This works for cars and trucks, not for boats
exemplar = FactoryGirl.create(model, id: 1, hp: 600, wheels: 4)
# A bunch of assertions
end
end
I can assign id and hp to all models but while cars and trucks have wheels, boats have motors. Is there a way to in the create call essentially say "If this method is defined, then use it, if not then ignore it"
What I would like to be able to do is call exemplar = FactoryGirl.create(model, id: 1, hp: 600, wheels: 4, motors: 2) and have it work across the board creating 3 objects:
If you use rspec as a test framework,use shared examples in the current context.
This will allow you to build each object as you want, and have them all go through the same tests. Example:
groupe_example 'object' do
it 'has a valid factory' do
expect(object).to be_valid
end
end
describe Car do
let(:object){ create(:car_with_some_options) }
include_examples 'object'
end
describe Truck do
let(:object){ create(:truck_with_other_options) }
include_examples 'object'
end
Otherwise, you should go for a solution like:
setup do
@models = {:car => {hp: 600}, :truck => { wheels: 8, hp: 1000} }
end
test 'something awesome' do
@models.each do |model, params|
# This works for cars and trucks, not for boats
exemplar = FactoryGirl.create(model, params)
# A bunch of assertions
end
end
which can be reformated better with different factories. For instance, if you create :default_car, :default_truck, etc factories for each of your model, you can then set whatever parameters you want there and then plain call them through FactoryGirl.create without having to worry about the parameters in your test.
================== EDIT ========================
If you really want to test whether the parameter is defined, you can either use attributes. A more comprehensive answer is here
Or, more simple, you can check whether there is a writer operator:
model.public_send(:wheels=, 4) if model.respond_to? :wheels=
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With