2014-05-22 14 views
12

Ho un array di hash, che per amor di discussione si presenta così:Rspec partita array di hash

[{"foo"=>"1", "bar"=>"1"}, {"foo"=>"2", "bar"=>"2"}] 

Utilizzando Rspec, voglio verificare se "foo" => "2" esiste nella matrice, ma io don' t importa se è il primo o il secondo oggetto. Ho provato:

[{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}].should include("foo" => "2")) 

Ma questo non funziona, in quanto gli hash devono corrispondere esattamente. C'è un modo per testare parzialmente i contenuti di hash?

+0

'[{" foo "=>" 1 "," bar "=>" 2 "}, {" foo "=>" 2 "," bar "=>" 2 "}]. flat_map (&: to_a) .should include ([ "foo", "2"]) funzionerà anche. –

risposta

4

È possibile utilizzare il metodo any?. Vedere this per la documentazione.

hashes = [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}] 
expect(hashes.any? { |hash| hash['foo'] == '2' }).to be_true 
0

Se il test separato di hash non è un requisito rigoroso lo farei in questo modo:

[{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}].map{ |d| d["foo"] }.should include("2") 
24

che ne dici?

hashes = [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}] 
expect(hashes).to include(include('foo' => '2')) 
+1

E se vuoi tutto invece di qualsiasi, beh, puoi usare 'all': expect (hashes) .to all (include ('foo' => '2')) –

+0

documenti per' all' qui: https: //www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/all-matcher – Kris

+4

Questo funziona, ma lo definirei come: 'expect (hashes) .to include (a_hash_including (" foo " => "2")) ' –

1

è possibile utilizzare matchers componibili

http://rspec.info/blog/2014/01/new-in-rspec-3-composable-matchers/

ma preferisco definire un matcher personalizzato come questo

require 'rspec/expectations' 

RSpec::Matchers.define :include_hash_matching do |expected| 
    match do |array_of_hashes| 
    array_of_hashes.any? { |element| element.slice(*expected.keys) == expected } 
    end 
end 

e utilizzarlo nelle specifiche come questo

describe RSpec::Matchers do 
    describe '#include_hash_matching' do 
    subject(:array_of_hashes) do 
     [ 
     { 
      'foo' => '1', 
      'bar' => '2' 
     }, { 
      'foo' => '2', 
      'bar' => '2' 
     } 
     ] 
    end 

    it { is_expected.to include_hash_matching('foo' => '1') } 

    it { is_expected.to include_hash_matching('foo' => '2') } 

    it { is_expected.to include_hash_matching('bar' => '2') } 

    it { is_expected.not_to include_hash_matching('bar' => '1') } 

    it { is_expected.to include_hash_matching('foo' => '1', 'bar' => '2') } 

    it { is_expected.not_to include_hash_matching('foo' => '1', 'bar' => '1') } 

    it 'ignores the order of the keys' do 
     is_expected.to include_hash_matching('bar' => '2', 'foo' => '1') 
    end 
    end 
end 


Finished in 0.05894 seconds 
7 examples, 0 failures 
Problemi correlati