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 containsexpect.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.