Multiple fetch calls using fetchMock & `userEvent.click` within a `test.each` using React Testing Library

Viewed 372

I'm looking to test a number of outcomes given the respons of a callback to an endpoit we are making requests to.

Given the code below:

describe('when I click the "continue to shop" button', () => {
test.only.each`
    applicationStatus                     | routeName                   | routeURL
    ${'CASH_ACCEPT'}                      | ${'Checkout Shipping'}      | ${'/checkout/shipping.page'}
    ${'DECLINED'}                         | ${'Account Rejected'}       | ${'/account/application/accountRejected.page'}
    ${'EXISTING_ACCOUNT_PROFILE_MATCHED'} | ${'Existing Account Found'} | ${'/account/accountFound.page?email=c***********4@example.com'}
    ${'a non-recognised'}                 | ${'Server Error'}           | ${'/serverError.page'}
`(
    'then the $applicationStatus response should take me to the $routeName page',
    async ({ applicationStatus, routeURL }) => {
        fetchMock.post(`/api/account-application/applications`, {
            data: {
                id: '123',
                type: 'account-application',
                attributes: {
                    applicationStatus: `${applicationStatus}`,
                    email: 't*********@example.com',
                },
            },
        });

        const component = render(<Benefits experiments={experiments} />);

        await act(async () => {
            await userEvent.click(component.getByText(/Continue to shop/i));
        });

        expect(component.getByTestId('loading-overlay'));

        // eslint-disable-next-line security/detect-non-literal-fs-filename
        expect(global.open).toBeCalledWith(`${routeURL}`, '_self');
    },
);

I would expect each test iteration to be fired only once However, it seems that each test is faliing. It seems that the userEvent.click is happening more than once and is saving the previous click:

Expected: "/account/accountFound.page?email=c_**\***_4@example.com", "\_self"
Received
1: "/checkout/shipping.page", "\_self"
2: "/account/application/accountRejected.page", "\_self"
3: "/account/accountFound.page?email=t**\***@example.com", "\_self"

Number of calls: 3

My understanding is that after each test,cleanup is ran and eveything should be reset before the next. Can anyone see what I am doing wrong here? Thanks!

1 Answers

It's expect(global.open) assertion that fails, not userEvent.click.

Jest doesn't reset spy calls by default, and no manual cleanup is performed in provided code.

Use resetAllMocks or restoreAllMocks:

afterEach(() => {
  jest.restoreAllMocks();
});

The latter requires to set up global.open spy before each test and not only once.

Or better, enable resetMocks or restoreMocks configuration option, because cross-contamination is almost never desirable in well-written tests.

Related