I have a unit test test case created with mocha and chai's expect where I deeply compare an array of value objects to the parsed content of a JSON file.
My record object has about 20 properties, and currently only the price can cause a mismatch. On a diff, I only see five of them.
expect(records).to.deep.equal(expected);
"data": {
- "price": 3578
+ "price": 3438
"not_important": "foo"
"also_not_important": "bar"
}
"data": {
- "price": 1828
+ "price": 1698
"not_important": "foo"
"also_not_important": "bar"
}
This is useful default in most cases, yet in this one it obfuscates which specific data object is breaking the assertions, as I only see redundant data here.
Assume there is a important
property in the data object that would make it quite clear what expectation is breaking the test. Therefore, I would like to be able to either configure what properties are shown or to display the entire object in the diff.
How can I configure mocha's diff display?
Here is a contrived meta-syntactic example showcasing the problem:
import {expect} from "chai";
describe(("diff problem"), () => {
it("should show case that the diff is not shown properly", () => {
const actual = {
a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: "THIS IS IMPORTANT",
};
const expected = {
...actual,
a: 0,
};
return expect(actual).to.deep.equal(expected);
});
});
The output of that testcase will be:
2) SourceParser diff problem should show entire diff on error of one property:
AssertionError: expected { Object (a, troiz, ...) } to deeply equal { Object (a, troiz, ...) }
+ expected - actual
{
- "a": 1
+ "a": 0
"bar": 0
"baz": 2
"buzz": 4
"fizz": 5
Yet it would be helpful to see: important: "THIS IS IMPORTANT"
as well.
Here is the modified example for the array case:
describe(("diff problem with an array"), () => {
it("should show case that the diff is not shown properly for deep equal of arrays", () => {
const anEntity = {
a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: "IMPORTANT", // assume that each item has a unique important property, which is why it's helpful for it to be shown
};
const offendingItem = {
...anEntity,
a: 0,
};
const actual = [
anEntity,
offendingItem,
anEntity,
];
const expected = [
anEntity,
anEntity,
anEntity,
];
return expect(actual).to.deep.equal(expected);
});
The output will be:
AssertionError: expected [ Array(3) ] to deeply equal [ Array(3) ]
+ expected - actual
"troiz": 0
"waldo": 115
}
{
- "a": 0
+ "a": 1
"bar": 0
"baz": 2
"buzz": 4
"fizz": 5
and it won't get better with Louis' answer modifying chai as it only dumps the entire actual array first and then shows the non-helpful diff:
AssertionError: expected [ { a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: 'IMPORTANT' },
{ a: 0,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: 'IMPORTANT' },
{ a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: 'IMPORTANT' } ] to deeply equal [ { a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: 'IMPORTANT' },
{ a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: 'IMPORTANT' },
{ a: 1,
troiz: 0,
bar: 0,
baz: 2,
poit: 3,
narf: 4,
fizzbuzz: 117,
fizz: 5,
buzz: 4,
waldo: 115,
mos: 85465,
important: 'IMPORTANT' } ]
+ expected - actual
"troiz": 0
"waldo": 115
}
{
- "a": 0
+ "a": 1
"bar": 0
"baz": 2
"buzz": 4
"fizz": 5
You can add --inline-diffs
to the mocha command, which will show the entire object with line numbers and inline diffs:
mocha --inline-diffs YourSpec.js
The documentation is a bit misleading: https://mochajs.org/#diffs