javascriptjsonreact-nativejestjsfetch-api

Jest - TypeError: response.json is not a function


We are unit testing a React-Native application (using Jest) which does various API calls using fetch.

We have mocked calls to fetch in our API call functions in order to test them. This works well so far. We also have functions that combine these API calls and operate some logic on them.

For example, here is one function that, given a token, will get the related user's first project (project[0]) and return the list of items from this project.

export async function getAllItems(token) {
  try {
    const response = await getCurrentUser(token); // fetch called inside
    const responseJson = await response.json();
    const allItemsResp = await getAllItemsFromSpecificProject(
      token,
      responseJson.projectIds[0],
    );                                            // fetch called inside
    return await allItemsResp.json();
  } catch (error) {
    console.log(error);
    return null;
  }
}

Both functions getCurrentUser and getAllItemsFromSpecificProject are simple fetch calls and are currently mocked properly. Here one test that tries to test the getAllItems function:

it('Gets all items', async () => {
  getAccessTokenMockFetch();
  const token = await getAccessToken('usherbrooke@powertree.io', 'test!23');

  getAllItemsMockFetch();
  const items = await getAllItems(token.response.access_token);

  expect(items.response.length).toEqual(3);
});

For clarity, here is how getAccessTokenMockFetch is done. getAllItemsMockFetch is almost identical (with different data in the response):

function getAccessTokenMockFetch() {
  global.fetch = jest.fn().mockImplementation(() => {
    promise = new Promise((resolve, reject) => {
      resolve(accepted);
    });

    return promise;
  });
}

where accepted contains the JSON content of a successful call. When we run this test, we get the following error:

TypeError: Cannot read property 'response' of null

And we console.log this one in the catch:

TypeError: response.json is not a function

which explains why response is null. It seems the json() call is not understood and I don't know how to mock it. I have done tons of research on Stack Overflow and beyond, but we have found nothing that helps me understand how to solve this issue. This might indicate that I am going the wrong way about this, which is quite possible since I'm new to JavaScript, React Native, and Jest.


Solution

  • One thing to try is giving it a fake json to call, like this:

    const mockFetch = Promise.resolve({ json: () => Promise.resolve(accepted) });
    global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);