2014-07-08 35 views
3

我已經抽象出我的模型,以便能夠同時測試多個模型。問題是一些模型有不同的參數。以下面的示例架構。如果定義了參數,則指定一個參數

架構(簡體)

# 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 

我可以分配idhp於所有車型,但同時汽車和卡車有wheels,船有motors。有沒有辦法在create呼叫本質上說:「如果這種方法定義,然後使用它,如果沒有,然後忽略它」

我希望能夠做的是呼籲exemplar = FactoryGirl.create(model, id: 1, hp: 600, wheels: 4, motors: 2)並讓它跨越板創建3個對象:

  1. 車:ID = 1,HP = 600,輪子= 4
  2. 卡車:ID = 1,HP = 600,輪子= 4
  3. 船:ID = 1,馬力= 600,馬達= 2

回答

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簡單地調用它們,而不必擔心測試中的參數。編輯========================

如果您確實想測試參數是否已定義,則可以使用attributes。一個更全面的回答是here

,或者更簡單,你可以檢查是否有一個作家運營商:

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