Unit Tests Failing After Updating React Scripts from v.3.4.4 to v.4.0.3

Viewed 681

I'm working on a new project for a client and have been asked to update create-react-app (react-scripts) from v.2.0.5 to v.4.0.3. I did that, and a bunch of unit tests failed. I went back through the project and isolated the breaking change to be the update from react-scripts 3.4.4 to 4.0.0.

Basically, the main error I'm seeing seems to apply to any tests running against async/await methods. Jest reports that the test times out but these tests are only timing out because they are failing. They all pass without issue on an earlier version of react-scripts (and by extension an earlier version of Jest I'd guess).

thrown: "Exceeded timeout of 5000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

The timeout seems to be relating to an issue with promises as it's preceeded by this error:

TypeError: Cannot read property 'then' of undefined

Along with a fairly indecipherable stack trace that lists a load of node modules.

Here's an example of the test that's failing:

 test('dispatching fetchPublishedArticlesAuthors action causes an API GET and updates the store', async (done) => {

    const options = { page: 0, size: 20, sort: 'createdBy.firstName,asc' };

    store.dispatch(fetchPublishedArticlesAuthors(options));

    const state = await stateChange(store);

    expect(fetch).toHaveBeenCalledWith(
      `https://content.onehub.test/articles/authors?page=0&size=20&sort=createdBy.firstName%2Casc`,
       expect.objectContaining({ method: 'GET' }),
    );

    expect(getPublishedArticlesAuthors(state)).toMatchSnapshot();

    done();
  });

The await stateChange(store) references this method:

export function stateChange(store) {
  return new Promise((resolve) => {
    let currentState = store.getState();
    store.subscribe(() => {
      const newState = store.getState();
      if (newState !== currentState) {
        resolve(newState);
      }
      currentState = newState;
    });
  });
}

This method works without issue on another project running react-scripts 4.0.3 so I don't think that it's the issue per se but it is failing to return anything if I'm not mistaken.

Store is mocked as follows:

beforeEach(() => {
    store = mockStore({ initialState, reducers, rootSaga: sagas });
    fetch.mockClear();
  });

Any tips on where to start? Confused as to why it fails on a more recent version but passes on an earlier one.

1 Answers

The solution was to set resetMocks to false. I tried doing this in Jest config but couldn't get it working so just added it directly to package.json:

"jest": {
    "resetMocks": false
}

It wasn't obvious from the failing tests but having read the release notes you can see that the version of Jest used by Create React App changed from v24 to v26. In the process, resetMocks is set to true which was breaking the implementation in the test above, causing them all to time out.

Related