How can I match an array of results in a sinon matcher?
For example, how can this code work?
var mystub = sinon.stub();
var myarg = { val: 1, mylist: [ {a:1}, {b:2}, {c:3,d:4} ] };
mystub(myarg);
sinon.assert.calledOnce(mystub).withArgs(
sinon.match({val: 1, mylist: [{a:1},{b:2},{c:3,d:4}]}) // this doesn't work
);
How can I get this to work? (Note that in my test, I don't have access to myarg - so I need to match it).
Obviously, I could write a custom function matcher, but I'm looking for something a bit easier to read and write.
This is an old posting, but I couldn't find the right answer for this question.
Sinon supports nested matchers. So to test the matching of deep object, you can do the following:
const mystub = sinon.stub();
const myarg = {
val: 1,
mylist: [{ a: 1, x: 'foo' }, { b: 2, y: 'bar' }, { c: 3, d: 4, e: 5 } ],
};
mystub(myarg);
sinon.assert.calledOnce(mystub);
sinon.assert.calledWithMatch(mystub, {
val: 1,
mylist: [
sinon.match({ a: 1 }),
sinon.match({ b: 2 }),
sinon.match({ c: 3, d: 4 }),
],
});
Custom matcher.
I recommend writing your own custom sinon matcher.
You can write it in a way that it is general and easy to read when it gets used.
Here is an example approach:
// usage
...withArgs(sinon.match(deepMatch({
val: 1,
mylist: [{a:1}, {b:2}, {c:3,d:4}]
})));
// custom matcher
const deepMatch = (expectation) => (actual) => {
return Object.keys(expectation).every(key => {
if (checkIfItsObject(expectation[key])) {
// value is also an object, go deeper and then compare etc.
} else {
// compare and return boolean value accordingly
}
});
};
// note: checkIfItsObject is pseudocode - there are many ways to
// check if an object is an object so I did not want to complicate
// this code example here
The custom matching function in the accepted answer is useful to know about but total overkill for this simple use case. To build on the useful answer from Eryk Warren, how about this:
// match each element of the actual array against the corresponding entry in the expected array
sinon.assert.match(actual, expected.map(sinon.match));
Sinon has matchers on the content of arrays, for example, sinon.match.array.deepEquals
This works:
var mystub = sinon.stub();
var myarg = { val: 1, mylist: [ {a:1}, {b:2}, {c:3,d:4} ] };
mystub(myarg);
sinon.assert.calledWith(mystub,
sinon.match({
val: 1,
mylist: sinon.match.array.deepEquals([ {a:1}, {b:2}, {c:3,d:4} ])
})
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With