Reputation: 2605
I'm trying to mock node-fetch with jest for my azure functions. In the test I have the following:
index.test.ts
jest.mock("node-fetch");
import fetch from "node-fetch";
const {Response} = jest.requireActual("node-fetch");
// Setup code here...
const expectedResult: User = {
user_id: "1",
email: "[email protected]",
name: "testUser",
nickname: "test",
picture: "pic",
app_metadata: {
email: "[email protected]"
}
};
(fetch as jest.MockedFunction<typeof fetch>).mockReturnValue(new Response(JSON.stringify(expectedResult)));
When I call it I'm doing the following:
index.ts
const options = {
method: 'PATCH',
headers: { "Content-Type": 'application/json', authorization: `Bearer ${accessToken}`},
body: body
};
const userResponse = await fetch(usersEndpoint, options);
const jsonResult = await userResponse.json();
context.res = {
body: jsonResult
};
When it hits the "await userResponse.json()" I get "body used already for" error. I have another test that is set up in a similar manner which works so I'm not sure why it's saying the body is used up from the await fetch call. Any help would be appreciated.
Upvotes: 9
Views: 20253
Reputation: 222493
Response object is supposed to be used once per request while mocked fetch
returns the same object for multiple requests. Also, it should return a promise of a response, not a response itself.
A correct way to mock it is:
fetch.mockImplementation(() => Promise.resolve(
new Response(JSON.stringify(expectedResult))
));
It's unnecessary to use Response
and follow the restrictions it imposes, especially since there's no native Response
in Node.
It can be:
fetch.mockResolvedValue({
json: jest.fn(() => expectedResult)
});
Upvotes: 6
Reputation: 2605
My problem was I had a call to another function that used fetch which was resolving my mock implementation. Once I mocked that return value:
(fetch as jest.MockedFunction<typeof fetch>).mockReturnValue(new Response(JSON.stringify(expectedResult)));
ended up working.
@Estus Flask's answer also ended up working.
Upvotes: 0