tjukes
tjukes

Reputation: 143

RSpec: Is there a way to check for a nested hash key at any level?

I expect my hash to look like one of these two:

{metadata: {SOME_UNKNOWN_KEY: {transaction_id: 123456}}}
{metadata: {transaction_id: 123456}}

If I'm looking for the key :transaction_id, I understand that I can use hash_including to expect a nested key that should be in a particular place, but I'd like to be able to do something like this to cover both options:

expect(something).
  to receive(some_method).
  with(hash_including(metadata: hash_including_anywhere(:transaction_id)))

Is this possible?

Upvotes: 2

Views: 1677

Answers (1)

Greg
Greg

Reputation: 6649

Sure it's possible!

Looking at how hash_including is implemented one can see that it's a simple matcher class there:

https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb#L70

HashIncluding matcher is based on BaseHashMatcher and it looks like if you played with some recursive approach to check if there's the key hiding somewhere deeper you should be good to go:

https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/argument_matchers.rb#L183

You can start from reading the specs for hash_including to get yourself started: https://github.com/rspec/rspec-mocks/blob/master/spec/rspec/mocks/hash_including_matcher_spec.rb

Defining your own matcher sounds scary because they work like magic in our tests, but they are actually not that complicated to write.

Upvotes: 1

Related Questions