I'm using Mocha for unit testing and Chai for assertions.
I'd like to find an easy to use solution to check if an object has the structure and properties as defined in my comparison object. But I don't need the objects to be completely equal. The subject under test should contain at least all the properties in my test object, but it might also contain other properties which are not under test at that moment.
So, I want to test a unit to check if the object it returns has at least a property named 'foo', which itself is an object that at least contains the property 'bar' with value 10. So, I have this expected outcome to test against:
var expected = {foo: {bar: 10}};
I call my unit and have my test subject in a variable sut
:
var sut = MyUnit.myFunction();
So for various suts, I expect these outcomes:
// Success. Exact match
{foo: {bar: 10}}
// Fail. Structure is ok, but property value is wrong.
{foo: {bar: 11}}
// Fail. property bar is missing.
{foo: {qux: 20}}
// Success. All properties match. Extra properties (baz) in sut are ignored:
{baz: 'a', foo: {bar: 10, baz: 20}}
And then I want to compare it in a convenient way. I could test all properties individually or split it in a number of tests, but I hoped I could do something like
sut.should.deep.contain.all(expected);
However, I got the following surprising result, even if the objects are exactly the same:
AssertionError: expected { foo: { bar: 10 } } to have a property 'foo' of { bar: 10 }, but got { bar: 10 }
Of course I tried this, and a couple of other variations. The simplest testing for equality, doesn't work if the object contains extra properties.
sut.should.eql(expected);
AssertionError: expected { foo: { bar: 10, qux: 20 } } to deeply equal { foo: { bar: 10 } }
I've tested other combinations of have
and contains
together with deep
, any
or all
, but none satisfied my wish.
I found the duplicate question "Chai deep contains assertion on nested objects", but the only (downvoted) answer doesn't make sense. It calls deep.eql
which is redundant, and above that it just doesn't work, because it tests for strict equality.
I do know I can test all properties separately, but I would be nice to have a readable, single-statement way to test if one object is 'a subset of' the other.
Update: I ended up using the Shallow Deep Equal plugin for Chai.