Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec partial match against a nested hash

Tags:

rspec

I've got a JSON structure that I'd like to match a single nested element in, while ignoring other data. The JSON looks like this (minimally):

{   "employee": {     "id": 1,     "jobs_count": 0   },   "messages": [ "something" ] } 

Here's what I'm using right now:

response_json = JSON.parse(response.body) expect(response_json).to include("employee") expect(response_json["employee"]).to include("jobs_count" => 0) 

What I'd like to do is something like:

expect(response_json).to include("employee" => { "jobs_count" => 0 }) 

Unfortunately, include requires an exact match for anything but a simple top-level key check (at least with that syntax).

Is there any way to partially match a nested hash while ignoring the rest of the structure?

like image 829
Jim Stewart Avatar asked Oct 30 '16 03:10

Jim Stewart


2 Answers

You are able to use and nest the hash_including method for these matchers.

Using your example, you can rewrite your test code to look like:

expect(response_json).to include(hash_including({   employee: hash_including(jobs_count: 0) })) 

(or if response_json is a single object, replace include with match)

This will also work when dealing with .with constraints, for example:

expect(object).to receive(:method).with(hash_including(some: 'value')) 
like image 123
fatty Avatar answered Sep 17 '22 15:09

fatty


With rspec 3.6.0, this works for me:

expect(subject).to match(a_hash_including(key: value)) 
like image 39
compiledweird Avatar answered Sep 18 '22 15:09

compiledweird