Partially matching object, array and function with Jest
Tags: jest, typescript, unittest, tdd
Published: 2023-06-01 14:16:42

## [JestJs](https://jestjs.io/) 🃏 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:
```javascript
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:
```javascript
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:
```javascript
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:
```javascript
expect(resultFixtureObject).toEqual(
 expect.objectContaining({
  finances: expect.objectContaining({
   incomes: expect.arrayContaining([
    {
     type: 'rent',
     amount: 12000,
     currency: '$',
    },
   ]),
  }),
 })
);
```
or multiple, complete or partial matches:
```javascript
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:
```javascript
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',
    }),
   ]),
  }),
 })
);
```
## Complete test file with comments inside
{% embed https://gist.github.com/srnux/05611e7d2a8eda809a74360af85340d2.js %}