Jest partial matching on objects, arrays and functions

Emma Goto 🍙 - Mar 11 '21 - - Dev Community

Sometimes with Jest, you only need to test part of an object exists, or test on a subset of an array. We can do this using Jest’s partial matchers.

In this post I will cover:

  • Using Jest’s objectContaining to match on certain key/value pairs in objects
  • Using Jest’s arrayContaining to match on certain values in arrays
  • How to use partial matching with Jest’s toHaveBeenCalledWith

Object partial matching with Jest’s objectContaining

When you want to test the subset of an object, or a specific key/value pair, you can use the objectContaining matcher.

test('should contain important value in object', () => {
    const object = {
        important: 'important',
        ignore: 'ignore',
    };

    expect(object).toEqual(expect.objectContaining({
        important: 'important'
    }));
d});
Enter fullscreen mode Exit fullscreen mode

This test will pass as long as the object contains important: 'important'.

Nested object partial matching

If you are looking for a value in a nested object, you can also nest objectContaining.

test('should contain important value in nested object', () => {
    const nestedObject = {
        ignore: 'ignore',
        payload: {
           important: 'important',
           ignore: 'ignore',
        },
    };

    expect(nestedObject).toEqual(
        expect.objectContaining({
            payload: expect.objectContaining({
                important: 'important',
            }),
        })
    );
});
Enter fullscreen mode Exit fullscreen mode

Array partial matching with Jest’s arrayContaining

As well as objects, you might only care about certain values in an array. In this case, you can use arrayContaining for partial matching on arrays.

test('should contain important value in array', () => {
    const array = [
        'ignore', 
        'important'
    ];

    expect(array).toEqual(expect.arrayContaining(['important']))
});
Enter fullscreen mode Exit fullscreen mode

This test will pass as long as the array contains the string 'important'.

Match an array in any order (unordered array)

The arrayContaining matcher will also work regardless of the order of your array.

test('should contain important values in array, in any order', () => {
    const array = [
        'ignore', 
        'important',
        'alsoImportant',
        'veryImportant',
        'veryVeryImportant',
    ];

    expect(array).toEqual(expect.arrayContaining(
        ['veryVeryImportant', 'veryImportant', 'alsoImportant', 'important']
    ));
});
Enter fullscreen mode Exit fullscreen mode

If you wanted to make sure that the array contained values in any order, but didn’t contain any other values, you could assert that the length of the array is as expected.

test('should contain only the important values in array, in any order', () => {
    const array = [
        'important',
        'alsoImportant',
        'veryImportant',
    ];

    expect(array).toEqual(expect.arrayContaining(
        ['veryImportant', 'alsoImportant', 'important']
    ));
    expect(array).toHaveLength(3);
});
Enter fullscreen mode Exit fullscreen mode

Partial matching objects in an array

With an array of objects, we can use a combination of Jest’s arrayContaining and objectContaining. This will let you assert on a specific object in an array (and even a specific value inside of that object).

test('should contain important objects in array', () => {
    const array = [
        { 
            important: 'important',
            ignore: 'ignore'
        },
        {
            ignore: 'ignore',
        }
    ];

    expect(array).toEqual(expect.arrayContaining(
        [expect.objectContaining({ important: 'important' })]
    ));
});
Enter fullscreen mode Exit fullscreen mode

Matching on arguments in function calls with Jest’s toHaveBeenCalledWith

We use toHaveBeenCalledWith when we want to assert that a function was called with a specific set of arguments. If you only care about a specific argument in a function call, you can replace the other arguments with expect.anything().

test('should have been called with specific argument', () => {
    const mockFunction = jest.fn();

    mockFunction('ignore', 'ignore', 'important');

    expect(mockFunction).toHaveBeenCalledWith(
        expect.anything(), expect.anything(), 'important'
    );
});
Enter fullscreen mode Exit fullscreen mode

If you want to be a bit more specific, you can also use expect.any() if you want to specify the type of the other arguments, such as a String or Object.

mockFunction({ignore: 'ignore'}, 'ignore', 'important');

expect(mockFunction).toHaveBeenCalledWith(
    expect.any(Object), expect.any(String), 'important'
);
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player