Advertisements

Jest has the ability to check for partial matches on arrays and objects. Let us see how to do partial matching in Jest.

expect has powerful matcher methods for partial matching, and they can also be combined with the tohavebeencalledwith method.

Matching objects partially using expect.objectContaining

When trying only to match a subset of an object’s properties, we can use the objectContaining matcher.

test('should match website name', () => {
    const website = {
        name: 'Wisdom Geek',
        url: 'https://www.wisdomgeek.com',
    };
        
    expect(website).toEqual(expect.objectContaining({
        name: 'Wisdom Geek'
    }));
d});
JavaScript

The above test will pass if the name attribute matches in the test. The other key-value pairs in the object have no relevance to the outcome of the test.

The above test could have been easily rewritten as:

expect(website.name).toEqual('Wisdom Geek');
JavaScript

But partial matching in Jest shines when multiple properties need to be tested. For example:

test('should match website attributes', () => {
    const website = {
        name: 'Wisdom Geek',
        url: 'https://www.wisdomgeek.com',
        author: 'Saransh Kataria',
    };
        
    expect(website).toEqual(expect.objectContaining({
        name: 'Wisdom Geek'
        url: 'https://www.wisdomgeek.com',
    }));
d});
JavaScript

Is more readable and maintainable than

expect(website.name).toEqual('Wisdom Geek');
expect(website.url).toEqual('https://www.wisdomgeek.com');
JavaScript

There is only one assert statement with the partial matching statement, and all related properties are tested in it.

Partial matching on nested objects

The objectContaining matcher can also be used to match nested objects.

test('should match author name in nested object', () => {
    const website = {
        name: 'Wisdom Geek',
        url: 'https://www.wisdomgeek.com',
        author: {
          name: 'Saransh Kataria',
        }
    };

    expect(nestedObject).toEqual(
        expect.objectContaining({
            author: expect.objectContaining({
                name: 'Saransh Kataria',
            }),
        })
    );
JavaScript

As long as the author name matches, the above test will always pass.

Matching arrays partially using expect.arrayContaining

Similarly, if we only care about matching partial values in an array, we can use arrayContaining.

test('should contain wisdomgeek in given array', () => {
    const array = [
        'irrelevant', 
        'wisdomgeek'
    ];

    expect(array).toEqual(expect.arrayContaining(['wisdomgeek']));
});
JavaScript

The above test passes as long as one of the entries in the given array is wisdomgeek.

It is also worth mentioning that arrayContaining works irrespective of the order of the array.

test('should contain wisdomgeek in given array', () => {
    const array = [
        'irrelevant', 
        'wisdomgeek',
        'foo'
    ];

    expect(array).toEqual(expect.arrayContaining(['foo', 'wisdomgeek']));
    // passes, order does not matter
});
JavaScript

This can then be used to check that the array does have all the elements that it should have and not in any particular order. If we wanted to check that it had only the items that we wanted it to have and nothing else, we could add an additional length check as well.

test('should contain wisdomgeek in given array', () => {
    const array = [
        'irrelevant', 
        'wisdomgeek',
    ];

    expect(array).toEqual(expect.arrayContaining(['foo', 'wisdomgeek']));
    expect(array).toHaveLength(2);
});
JavaScript

Combining object and array partial matching

We can combine the above two matchers to create various permutations and combinations if we wanted to do some advanced checks.

test('we should have ids 1 and 2', () => {
  const authors = [{id: 1, name: 'Saransh'}, {id: 2, name: 'Wisdom Geek'}];
  expect(authors).toEqual(
    expect.arrayContaining([
      expect.objectContaining({name: 'Saransh'}),
      expect.objectContaining({name: 'Wisdom Geek'})
    ])
  );
});
JavaScript

and

test('user 3 should be a friend of user', () => {
  const author = {
    id: 1,
    name: 'Saransh',
    posts: ['foo', 'bar', 'baz']
  };
  expect(author).toEqual(
    expect.objectContaining({
      posts: expect.arrayContaining(['foo'])
    })
  );
});
JavaScript

Partial match with toHaveBeenCalledWith arguments

These matchers can even be combined with Jest’s toHaveBeenCalledWith function. Using the combination of toHaveBeenCalledWith and partial, Jest tests can assert that a function was called with a particular argument.

test('test jest tohavebeencalledwith partial', () => {
    const mockFunction = jest.fn();

    mockFunction('foo', 'bar', 'baz');

    expect(mockFunction).toHaveBeenCalledWith(
       'foo', expect.anything(), expect.anything()
    );
});
JavaScript

And that is all, folks. I hope that this post helps you with writing some advanced test cases using partial matching. If you have any questions, do let us know in the comments.

Saransh Kataria

Born in Delhi, India, Saransh Kataria is the brain behind Wisdom Geek. Currently, Saransh is a software developer at a reputed firm in Austin, and he likes playing with new technologies to explore different possibilities. He holds an engineering degree in Computer Science. He also shares his passion for sharing knowledge as the community lead at Facebook Developer Circle Delhi, NCR which is a developer community in Delhi, India.

Share
Published by
Saransh Kataria
Tags: jest

Recent Posts

How To Get The Hash of A File In Node.js

While working on a project, I wanted to do an integrity check of a file…

2 weeks ago

Native popover API in HTML

Popovers have been a problem that was typically solved by using a third-party solution. But…

3 weeks ago

Node.js 20.6 adds built-in support for .env files

Node.js 20.6 added built-in support for the .env file. This is an excellent addition to the platform…

4 weeks ago

Object destructuring in TypeScript

Object destructuring is a powerful ES 6 feature that can help developers write cleaner code.…

1 month ago

Improve git clone performance in a CI pipeline

Have you felt particularly annoyed by the time it takes to clone a large repository,…

2 months ago

Fix: Hydration failed because the initial UI does not match what was rendered on the server

Within a React or Next.js app, if you encounter the error "Hydration failed because the…

2 months ago
Advertisements