toContainEqual fails when I try to test whether an object is in an array that is in a mongoose/mongodb object, even though the object is exactly the same as the one in the array.
This is my test snippet:
it('should be able to update document in conversations collection', async () => {
const mockMessageId = mongoose.Types.ObjectId();
const mockMessage = {
_id: mockMessageId,
type: 'TEXT',
content: 'testMessage',
};
await Conversation.findByIdAndUpdate(mockObjectId, {
$push: { messages: mockMessage },
});
const updatedConversation = await Conversation.findById(mockObjectId);
expect(updatedConversation.messages).toContainEqual(mockMessage);
});
which gives:
Error: expect(received).toContainEqual(expected) // deep equality
Expected value: {"_id": "5e599695fb41595b3093ada6", "content": "testMessage", "type": "TEXT"}
Received array: [{"_id": "5e599695fb41595b3093ada6", "content": "testMessage", "type": "TEXT"}]
toContainEqual should be able to match the object in the array and passes the test.
https://github.com/MrCreeper1008/jest-tocontainequal-issue
npx: installed 1 in 1.452s
System:
OS: macOS 10.15.1
CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Binaries:
Node: 10.17.0 - ~/.nvm/versions/node/v10.17.0/bin/node
Yarn: 1.22.0 - /usr/local/bin/yarn
npm: 6.11.3 - ~/.nvm/versions/node/v10.17.0/bin/npm
npmPackages:
jest: ^25.1.0 => 25.1.0
What I'm doing to avoid this is I reorder the keys and then stringify the objects before comparing. Kinda hacky, but it works.
Thanks for reporting and for providing a repo.
I've been looking at it, and it seems that the reason it is failing is because the items in createdConversation.messages contain more keys than just _id, type, content. createdConversation.messages also contains the following keys __parentArray, __index, $isDocumentArrayElement, $__, isNew, errors,
_doc, $locals, $op, $init.
You can see the error by changing the expectation to:
expect(createdConversation.messages[0]).toEqual({
_id: messageId,
type: "TEXT",
content: "test message"
});
To solve this, you can use this asymmetrical matcher _(expect.objectContaining(...))_
- expect(createdConversation.messages).toContainEqual({
- _id: messageId,
- type: 'TEXT',
- content: 'test message',
- });
+ expect(createdConversation.messages).toContainEqual(
+ expect.objectContaining({
+ _id: messageId,
+ type: "TEXT",
+ content: "test message"
+ })
+ );
Let me know if that seems to work for you and I can close the issue if needed 馃槃
Thank you so much for the detailed explanation! I'll look into it.
Edit: It works perfectly! Thank you again for helping me out. Closing this issue.
Most helpful comment
Thanks for reporting and for providing a repo.
I've been looking at it, and it seems that the reason it is failing is because the items in
createdConversation.messagescontain more keys than just_id, type, content.createdConversation.messagesalso contains the following keys__parentArray, __index, $isDocumentArrayElement, $__, isNew, errors, _doc, $locals, $op, $init.You can see the error by changing the expectation to:
To solve this, you can use this asymmetrical matcher _(
expect.objectContaining(...))_Let me know if that seems to work for you and I can close the issue if needed 馃槃