Ruby on rails 如果已定义参数,则指定该参数

Ruby on rails 如果已定义参数,则指定该参数,ruby-on-rails,ruby,factory-bot,Ruby On Rails,Ruby,Factory Bot,我已经抽象出我的模型,以便能够同时测试多个模型。问题是有些模型的参数不同。以下面的示例模式为例 模式(简化) 测试 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.cr

我已经抽象出我的模型,以便能够同时测试多个模型。问题是有些模型的参数不同。以下面的示例模式为例

模式(简化)

测试

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
分配给所有型号,但轿车和卡车有
车轮
,而船只有
电机
。有没有办法在
创建
调用中实质性地说“如果定义了此方法,则使用它,如果没有,则忽略它”

我想能够做的是调用
examplar=FactoryGirl.create(型号,id:1,hp:600,轮子:4,马达:2)
并让它全面工作创建3个对象:

  • 汽车:id=1,马力=600,车轮=4
  • 卡车:id=1,hp=600,车轮=4
  • 船:id=1,hp=600,电机=2

  • 如果使用rspec作为测试框架,请在当前上下文中使用

    这将允许您根据需要构建每个对象,并让它们都经过相同的测试。例如:

    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\u car、:default\u truck等工厂,则可以在那里设置所需的任何参数,然后通过FactoryGirl.create直接调用它们,而不必担心测试中的参数

    =========================编辑========================

    如果确实要测试参数是否已定义,可以使用
    属性
    。一个更全面的答案是

    或者,更简单地说,您可以检查是否存在writer操作符:

    model.public_send(:wheels=, 4) if model.respond_to? :wheels=
    
    model.public_send(:wheels=, 4) if model.respond_to? :wheels=