DEV Community

Luka Zmikic Engels
Luka Zmikic Engels

Posted on

Partially matching object, array and function with Jest

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: '$',
   },
  ],
 },
};
Enter fullscreen mode Exit fullscreen mode

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',
 })
);
Enter fullscreen mode Exit fullscreen mode

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()
  })
 })
);
Enter fullscreen mode Exit fullscreen mode

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: '$',
    },
   ]),
  }),
 })
);
Enter fullscreen mode Exit fullscreen mode

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',
    }),
   ]),
  }),
 })
);
Enter fullscreen mode Exit fullscreen mode

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',
    }),
   ]),
  }),
 })
);
Enter fullscreen mode Exit fullscreen mode

Complete test file with comments inside

Top comments (0)