Samuel Olekšák
Samuel Olekšák

Reputation: 388

Mocking functions called inside then() with jest

I am trying to test this function

const handleSave = () => {
    const cveIds = cveList.map(item => item.id);
    return setCveStatus({
        status_id: parseInt(statusId),
        cve: cveIds,
        status_text: justification
    })
    .then(() => !checkboxState && setSystemCveStatus({ cve: cveIds }))
    .then(updateRef);
};

which calls 2 functions setCveStatus and setSystemCveStatus which I am mocking

const setCveStatusMock = jest.fn(parameters => new Promise(resolve => resolve(parameters)));
const setSystemCveStatusMock = jest.fn(parameters => new Promise(resolve => resolve(parameters)));

deps.setCveStatus = setCveStatusMock;
deps.setSystemCveStatus = setSystemCveStatusMock;

and testing what are they called with

expect(setCveStatusMock).toBeCalledWith({
    status_id: 3,
    status_text: 'new',
    cve: ['CVE-2020-0001']
});

expect(setSystemCveStatusMock).toBeCalledWith({
    cve: ['CVE-2020-0001']
});

But the second expect fails, even though it shouldn't have. How can I mock and test functions called inside .then()?

Upvotes: 0

Views: 60

Answers (1)

Iku-turso
Iku-turso

Reputation: 21

One way to solve this elegantly is with asyncFn.

With that instead of:

const setCveStatusMock = jest.fn(parameters => new Promise(resolve => resolve(parameters)));

// ...

expect(setSystemCveStatusMock).toBeCalledWith({
    cve: ['CVE-2020-0001']
});

you can

import asyncFn from '@asyncFn/jest';
const setCveStatusMock = asyncFn();

// ...

// Resolve the call for setCveStatusMock and await for anything that happens as a result of that.
await setCveStatusMock.resolve();

// ...

expect(setSystemCveStatusMock).toBeCalledWith({
    cve: ['CVE-2020-0001']
});

Disclaimer: I am one of the authors.

Upvotes: 1

Related Questions