BobMorane
BobMorane

Reputation: 4296

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('[email protected]', '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.

Upvotes: 0

Views: 9789

Answers (3)

Matiz
Matiz

Reputation: 51

In my case I needed this specific test to run in node environment instead of jsdom. You can force a particular test to run in a different environment by putting this on top of the .spec file:

/**
 * @jest-environment node
 */

Upvotes: 0

andrej28
andrej28

Reputation: 21

I had a similar problem where I was getting this error while creating jest unit test.Here is my solution to creating helper function to create mock response.

function createMockResponse(
    body: any,
    status: number,
    statusText: string
  ): Response {
    return {
      ok: status >= 200 && status < 300,
      status,
      statusText,
      headers: {
        get: (headerName: string) => {
          if (headerName === 'content-type') {
            return 'application/json'
          }
          return null
        },
      },
      json: async () => body,
    } as unknown as Response
  }

Upvotes: 1

Emily Coleman
Emily Coleman

Reputation: 230

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);

Upvotes: 5

Related Questions