JestJs 🃏 Delightful JavaScript Testing
It is really delightful as the team states! For the last couple of years that is accompanying me in my daily struggles, it has shown it's worth. One of the best parts is the partial match on object, array and function, which will be the focus of this blog post.
Partially matching objects
Let's say you need to test a unit that changes just parts of an object. It is indifferent of the remaining parts of the object. Your unit test should check just the changes the unit influences.
In the code block below, a simple fixture containing some nested objects and arrays, which will be used in the following examples:
const resultFixtureObject = {
active: true,
id: 'e0e0e0e0-2b79-4eba-ab39-b2dfdb2f0eba',
firstName: 'Jester',
lastName: 'Magic',
finances: {
incomes: [
{
type: 'salary',
amount: 150000,
currency: '$',
},
{
type: 'dividend',
amount: 6000,
currency: '$',
},
{
type: 'rent',
amount: 12000,
currency: '$',
},
],
},
};
Match object
In the test below, the expected result object must match a few properties:
expect(resultFixtureObject).toEqual(
expect.objectContaining({
active: true,
id: 'e0e0e0e0-2b79-4eba-ab39-b2dfdb2f0eba',
firstName: 'Jester',
lastName: 'Magic',
})
);
Match nested object
You can match nested objects by simply nesting objectContaining() expectations. In this case, expecting object finances that must have nested object incomes. We do not care about the content of the incomes, in this unit test:
expect(resultFixtureObject).toEqual(
expect.objectContaining({
finances: expect.objectContaining({
incomes: expect.anything()
})
})
);
Partially matching arrays
Just as the objects, there is a way to partially match arrays. You can expect single or multiple item matches on an array.
Expecting one item to match:
expect(resultFixtureObject).toEqual(
expect.objectContaining({
finances: expect.objectContaining({
incomes: expect.arrayContaining([
{
type: 'rent',
amount: 12000,
currency: '$',
},
]),
}),
})
);
or multiple, complete or partial matches:
expect(resultFixtureObject).toEqual(
expect.objectContaining({
finances: expect.objectContaining({
incomes: expect.arrayContaining([
{
type: 'rent',
amount: 12000,
currency: '$',
},
expect.objectContaining({
type: 'salary',
}),
]),
}),
})
);
Partially matching function parameter calls
Aforementioned operations can be applied to toHaveBeenCalledWith() matcher as well.
Below a variant with toHaveBeenNthCalledWith() matcher. Verifying just the third call to the function:
const functionMock = jest.fn();
functionMock('string arg');
functionMock(['array arg']);
functionMock(resultFixtureObject);
expect(functionMock).toHaveBeenNthCalledWith(
3,
expect.objectContaining({
finances: expect.objectContaining({
incomes: expect.arrayContaining([
expect.objectContaining({
type: 'rent',
}),
expect.objectContaining({
type: 'salary',
}),
]),
}),
})
);
Top comments (0)