2013-12-18 196 views
11

我有一個充滿對象的json數組。Rspec:檢查數組是否包含包含屬性的對象

my_array = [{id => 6, name => "bob"}, 
      {id => 5, name => "jim"}, 
      {id => 2, name => "steve"}] 

我需要看看該數組是否包含一個包含設置爲5的屬性「id」的對象。「name」屬性是未知的。

如何在rspec中執行此操作?

我知道,如果我有屬性的名稱,我知道我可能只是這樣做:

my_array.should include({:id => 5, :name => "jim"}) 

回答

22
expect(myArray.find { |item| item[:id] == 5 }).to_not be_nil 

或與傳統應該語法

myArray.find { |item| item[:id] == 5 }.should_not be_nil 

請注意,myArray沒有下面的Ruby約定。變量使用下劃線

my_array 

沒有駝峯

myArray 
+0

教導正確的Ruby命名約定的獎勵積分。好樣的! –

+0

對於任何正在尋找RSpec 3解決方案的人來說,查看RSpecs新的可組合匹配器。 –

3

這隻會是值得的,如果你在做很多這樣的,但是你可以定義一個custom matcher

RSpec::Matchers.define :object_with_id do |expected| 
    match do |actual| 
    actual[:id] == expected 
    end 
    description do 
    "an object with id '#{expected}'" 
    end 
end 

# ... 

myArray.should include(object_with_id 5) 
0

這裏的客戶匹配器「include_object」(可能應該使用更好的名稱,因爲它只是檢查ID是否存在)

使用如下

obj = {id:1} 
objs = [{id: 1}, {id: 2}, {id: 3}] 
expect(objs).to include_object obj 

匹配器可以處理對象,Hashs(符號或字符串) 它還版畫只是ID對異常陣列爲了方便查閱,

RSpec::Matchers.define :include_object do |expected| 
    ids = [] 
    match do |actual| 
    ids = actual.collect { |item| item['id'] || item[:id] || item.id } 

    ids.find { |id| id.to_s == expected.id.to_s } 
    end 

    failure_message_for_should_not do |actual| 
    "expected that array with object id's #{ids} would contain the object with id '#{expected.id}'" 
    end 

    failure_message_for_should_not do |actual| 
    "expected that array with object id's #{ids} would not contain the object with id '#{expected.id}'" 
    end 
end 
1

認沽這any匹配器spec/support/matchers.rb並要求它在您的spec_helper.rb

RSpec::Matchers.define :any do |matcher| 
    match do |actual| 
    actual.any? do |item| 
     matcher.matches?(item) 
    end 
    end 
end 

然後你可以在示例中使用這樣的:

expect(my_array).to any(include(id: 5)) 
0

您可以展開一個數組,並檢查兩個數組的匹配喜歡這裏:

expect(my_array).to include(*compare_array) 

它會展開並匹配數組的每個值。

這是相同的:

expected([1, 3, 7]).to include(1,3,7) 

來源:Relish documentation

0

我會使用的RSpec 3的組合的include匹配,像這樣:

expect(my_array).to include(include(id: 5)) 

這將有更受益在發生故障時通過RSpec詳細輸出。

it 'expects to have element with id 3' do 
    my_array = [ 
    { id: 6, name: "bob" }, 
    { id: 5, name: "jim" }, 
    { id: 2, name: "steve" } 
    ] 
    expect(my_array).to include(include(id: 3)) 
end 

這將產生以下故障消息:

Failures: 

    1) Test expects to have element with id 
    Failure/Error: expect(my_array).to include(include(id: 3)) 

     expected [{:id => 6, :name => "bob"}, {:id => 5, :name => "jim"}, {:id => 2, :name => "steve"}] to include (include {:id => 3}) 
     Diff: 
     @@ -1,2 +1,2 @@ 
     -[(include {:id => 3})] 
     +[{:id=>6, :name=>"bob"}, {:id=>5, :name=>"jim"}, {:id=>2, :name=>"steve"}] 

延伸閱讀:

https://relishapp.com/rspec/rspec-expectations/docs/composing-matchers