I have a problem with testing my inversify-express-utils controller using jest in my typescript node app. As far as i can tell the test is failing when it should pass, the test is behaving as if I am calling expect(expected).toStrictEqual(actual)
when I am actually calling expect(expected).toEqual(actual)
. I apologise in advance for the amount of code I'm about to post but it really is the smallest example i could get to recreate the problem.
I have these two classes which should be equivalent.
export class CannotCompareClass {
public _data: string;
constructor(input: string) {
this._data = input;
}
toJSON() {
return {
data: this._data,
};
}
}
export class CanCompareClass {
constructor(public data: string) {}
toJSON() {
return {
data: this.data,
};
}
}
This is my controller:
import 'reflect-metadata';
import {
BaseHttpController,
controller,
httpGet,
IHttpActionResult,
} from 'inversify-express-utils';
import { CannotCompareClass, CanCompareClass } from './custom-class';
@controller('/')
export class TestController extends BaseHttpController {
constructor() {
super();
}
@httpGet('/')
public async cannotCompare(): Promise<IHttpActionResult> {
const input = 'value';
const instance = new CannotCompareClass(input);
return this.json(instance, 200);
}
@httpGet('/c')
public async canCompare(): Promise<IHttpActionResult> {
const instance = new CanCompareClass('value');
return this.json(instance, 200);
}
}
These are my tests
import { TestController } from '../src/controller';
import { CannotCompareClass } from '../src/custom-class';
describe('CanCompare', () => {
it('will pass and should pass', async () => {
const controller = new TestController();
const instance = await controller.canCompare();
const expectedResult = {
json: {
data: 'value',
},
statusCode: 200,
};
expect(instance).toEqual(expectedResult);
});
});
describe('CannotCompare', () => {
it('will fail but should pass', async () => {
const controller = new TestController();
const instance = await controller.cannotCompare();
const expectedResult = {
json: {
data: 'value',
},
statusCode: 200,
};
expect(instance).toEqual(expectedResult);
});
});
describe('CannotCompare', () => {
it('will fail and should fail', async () => {
const controller = new TestController();
const instance = await controller.cannotCompare();
const expectedResult = {
json: {
data: 'value',
},
statusCode: 200,
};
expect(instance).toStrictEqual(expectedResult);
});
});
describe('CannotCompare', () => {
it('will pass and should pass stringified', async () => {
const controller = new TestController();
const instance = await controller.cannotCompare();
const expectedResult = {
json: {
data: 'value',
},
statusCode: 200,
};
expect(JSON.stringify(instance)).toEqual(JSON.stringify(expectedResult));
});
});
describe('CannotCompare', () => {
it('will pass and should pass no controller', async () => {
const instance = new CannotCompareClass('value');
const expectedResult = { data: 'value' };
expect(instance.toJSON()).toEqual(expectedResult);
});
});
The tests "CannotCompare" it "will fail and should pass" and "CannotCompare" it "will fail and should fail" both fail for the same reason that the underlying type of the values being compared is different. See below:
- Expected - 1
+ Received + 1
- Object {
+ JsonResult {
"json": Object {
"data": "value",
},
"statusCode": 200,
}
Difference:
Compared values have no visual difference.Error:
However, toEqual() should only compare the values and not the type and for the CanCompare class it does indeed work like this, it is only the cannot compare class that it fails on.
Any insight into what the hell is going on here would be much appreciated.
There is a working demo here on StackBlitz link just run jest
in the terminal.