5.3 Nested Array/Object Containing/Not Containing

Jest Array of objects partial match with arrayContaining and objectContaining

In keeping with the user example, what if we wanted to check that we have the right ids for a list (array) of users.

By combining expect.objectContaining and expect.arrayContaining we can do a partial match on the objects in the array:

const users = [
  { id: 1, name: 'Hugo' },
  { id: 2, name: 'Francesco' }
];

test('we should have ids 1 and 2', () => {
  expect(users).toEqual(
    expect.arrayContaining([
      expect.objectContaining({ id: 1 }),
      expect.objectContaining({ id: 2 })
    ])
  );
});

Note: the parameter passed to arrayContaining must be an array, even if that array contains expect.objectContaining partial matches

We get the following passing test.

npx jest src/05.03
 PASS  src/05.03-nested-object-array-containing.test.js
  ✓ we should have ids 1 and 2 (4ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total

To do the same without expect.objectContaining or expect.arrayContaining, we would have needed to unpack the array or use find/some:

const users = [
  { id: 1, name: 'Hugo' },
  { id: 2, name: 'Francesco' }
];
test('example 1 > we should have ids 1 and 2', () => {
  const [first, second] = users;
  expect(first.id).toEqual(1);
  expect(second.id).toEqual(2);
});
test('example 2 > we should have ids 1 and 2', () => {
  expect(users.some(({ id }) => id === 1)).toBe(true);
  expect(users.some(({ id }) => id === 2)).toBe(true);
});

Jest Object with nested arrays partial match with objectContaining and arrayContaining

In keeping with the user example, what if we wanted to check that we have the right ids for a list (array) of friends for a user?

By combining expect.objectContaining and expect.arrayContaining we can do a partial match on fields that are arrays in the object:

const user = {
  id: 1,
  name: 'Hugo',
  friends: [3, 5, 22]
};
test('user 3 should be a friend of user', () => {
  expect(user).toEqual(
    expect.objectContaining({
      friends: expect.arrayContaining([3])
    })
  );
});

The test output is passing, as follows.

npx jest src/05.03-object-with-arrays.test.js
 PASS  src/05.03-object-with-arrays.test.js
  ✓ user 3 should be a friend of user (4ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total

To do the same without expect.objectContaining or expect.arrayContaining, we would have needed to use some:

const user = {
  id: 1,
  name: 'Hugo',
  friends: [3, 5, 22]
};
test('user 3 should be a friend of user', () => {
  expect(user.friends.some(f => f === 3)).toBe(true);
});

Jest array/object negative matches with not.objectContaining and not.arrayContaining

To check that something is not in an array or object, we can use expect.not.arrayContaining and expect.not.objectContaining respectively

const user = {
  id: 1,
  name: 'Hugo',
  friends: [3, 5, 22]
};
test('user 3 should be a friend of user', () => {
  expect(user).toEqual(
    expect.not.objectContaining({
      url: 'https://codewithhugo.com'
    })
  );
  // Can't be your own friend?
  expect(user.friends).toEqual(expect.not.arrayContaining([1]));
});

This passes as expected.

npx jest src/05.03-array-object-negative-match.test.js
 PASS  src/05.03-array-object-negative-match.test.js
  ✓ user 3 should be a friend of user (5ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total

We’ve now seen how to partially match arrays, objects and a nested combination of them both using expect.objectContaining() and expect.arrayContaining()

In the next section we’ll see how to match only some of the parameters a stub/mock is called with.

Jump to table of contents