2011-01-18 7 views
15

Nota per i futuri lettori: pensa che RSpec non consideri i tuoi Hash uguali? Uno potrebbe essere un OrderedHash, ma dal normale output di RSpec non si può dire. Questo è stato il problema che ha spinto questo post.Esiste un correttore RSpec2 per la corrispondenza degli hash?

domanda originale:

Supponiamo che io abbia una specifica dove voglio provare che un metodo genera l'hash appropriata.

it 'should generate the Hash correctly' do 
    expected = {:foo => 1, 'baz' => 2} 
    subject.some_method_that_should_generate_the_hash.should == expected 
end 

Questo spesso fallisce, poiché diversi hash con le stesse coppie di valori-chiave possono restituire loro coppie in un diverso ordine. Risultati assomigliano:

Failure/Error: subject.some_method_that_should_generate_the_hash.should == expected 
expected: {:foo => 1, 'baz' => 2}, 
    got: {'baz' => 2, :foo => 1} 

Per gli array, questo è risolto utilizzando l'operatore = ~. Tuttavia, questo non funziona per Hash. Per ora, ho fatto ricorso a

it 'should generate the Hash correctly' do 
    expected = {:foo => 1, 'baz' => 2} 
    subject.some_method_that_should_generate_the_hash.each {|k,v| 
    v.should == expected[k] 
    } 
end 

ma sembra inutilmente prolisso. Mi aspetto che ci sia una soluzione ovvia per questo. Sto trascurando qualcosa nei documenti o RSpec non ha un Corrispondente adatto per l'uguaglianza di Hash senza ordine?

risposta

17
describe 'Hash' do 
    let(:x) { { :a => 1, :b => 2 } } 
    let(:y) { { :b => 2, :a => 1 } } 

    it "should be equal with ==" do 
    x.should == y 
    end 
end 

pass. Non sono sicuro di quello che sta succedendo nel tuo caso specifico. Hai alcuni esempi che non riesci a condividere?

programmazione Ruby ha questo da dire:

uguaglianza - Due hash sono uguali se hanno lo stesso valore di default, che contengono lo stesso numero di chiavi, e il valore corrispondente a ciascun tasto in il primo hash è uguale (usando ==) a il valore per la stessa chiave nel secondo .

+0

Ieri ritardo ho trovato il problema: non stavo effettivamente confrontando due Hash: uno si era trasformato in un OrderedHash da qualche parte lungo la strada. Non puoi guardarlo dall'uscita RSpec e sono un po 'imbarazzato nel dire che non era la prima volta che cadevo in questa trappola:/ – Confusion

+3

Interessante. Quindi un OrderedHash e un Hash con le stesse coppie chiave/valore non sono considerati uguali: è bello saperlo. – zetetic

3

Credo che l'eql? controlli metodo solo che i due hash hanno lo stesso contenuto Così IIRC in Rspec2 si può fare:

expected = {:foo => 1, 'baz' => 2} 
    expected.should be_eql({'baz' => 2, :foo => 1}) 

ed il dosaggio deve passare

+0

o in RSpec 3, 'si aspettano (x) .to eql (y) ' – nruth

6

dal 8 mesi la gemma rspec-matchers ha il supporto per hash corrispondenti:

expected.should be_hash_matching(subhash_or_equal) 

Vedi qui per maggiori dettagli: https://github.com/rspec/rspec-expectations/pull/79

+0

sembra essere stato rimosso in rspec 3, ma '.to eql (x)' funziona – nruth

Problemi correlati