How to compare two hashes in RSpec?

I have two hashes h1 and h2 that I would like to compare with RSpec.

I want to check that the elements of h1 will be the same as h2 after some transformation, which we will call f . That is, I want to check that for each key k in h1 , h1[k] == f(h2[k]) .

For example, if all the values ​​in h2 are twice as large as the corresponding values ​​in h1 , then I want to check that for each key k in h1, h2[k] == h1[k] * 2 .

What is the right way to do this in RSpec? I am currently doing:

 h1 = ... expect( h2.all? { |k,v| v == f(h1[k]) } ).to be true 

but it seems awkward.

+7
ruby rspec
source share
4 answers

It seems that what you are testing is a transformation. I would like to write something like this:

 it "transforming something does something" do base_data = { k1: 1, k2: 2 } transformed_data = base_data.each_with_object({}) { |(k, v), t| t[k] = f(v) } expect(transformed_data).to eq( k1: 2, k2: 4, ) end 

For me, the description clearly states what we expect. Then from the test you can easily understand what the input and the expected result are. In addition, it uses a hash tag that will provide a good spread of the two hashes on failure:

 expected: {:k1=>2, :k2=>4} got: {:k1=>1, :k2=>4} (compared using ==) Diff: @@ -1,3 +1,3 @@ -:k1 => 2, +:k1 => 1, :k2 => 4, 

Although I would question the meaning of the relationship of key importance. Are these just test cases you are trying to execute? If so, I will just do each unique test. If there is anything more to this, then I can ask the question why the conversion method does not provide a hash to start with.

+4
source share
 h1.each do |k, v| expect(v).to eq(f(h2[k])) end 

For me, this seems more readable.

+1
source share

What about:

 h2 = f(h1) expect(h2.keys).to eq(h1.keys) # I assume you want this, too h1.keys.each do |k| expect(h2[k]).to eq(h1[k] * 2) end 

A little longer, but perhaps more readable?

+1
source share

For exact equality:

 expect(h1).to eq h2.map { |k, v| [k, f(v)] }.to_h 
0
source share

All Articles