我已经抽象出我的模型,可以同时测试多个模型。问题是某些模型具有不同的参数。以下为示例模式。
架构(简化)
# 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
测试
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
我可以为所有车型分配id
和hp
,但是当汽车和卡车有wheels
时,船只有motors
。有没有办法在create
调用中基本上说“如果定义了这个方法,那么使用它,如果没有则忽略它”
我希望能够做的是致电exemplar = FactoryGirl.create(model, id: 1, hp: 600, wheels: 4, motors: 2)
并让它全面运作,创建3个对象:
答案 0 :(得分:1)
如果您使用rspec作为测试框架,请在当前上下文中使用shared examples。
这将允许您根据需要构建每个对象,并让它们都经历相同的测试。例如:
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
否则,您应该寻求以下解决方案:
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
可以使用不同的工厂更好地重新格式化。例如,如果您为每个模型创建:default_car,:default_truck等工厂,则可以设置您想要的任何参数,然后通过FactoryGirl.create进行简单调用,而不必担心测试中的参数。 / p>
==================编辑========================
如果您确实想测试参数是否已定义,可以使用attributes
。更全面的答案是here
或者,更简单的是,您可以检查是否有编写器操作符:
model.public_send(:wheels=, 4) if model.respond_to? :wheels=