I managed to successfully mock fetch but I had to silence typescript. Here is the minimum reproducible example:
import { jest } from '@jest/globals';
jest.spyOn(global, 'fetch');
const TEST_URL = 'http://aztec-node-url.com/';
const setFetchMock = (response: any): void => {
// @ts-ignore
global.fetch.mockResolvedValue({
ok: true,
json: () => response,
});
};
export class HttpNode {
private baseUrl: string;
constructor(baseUrl: string) {
this.baseUrl = baseUrl.toString().replace(/\/$/, '');
}
public async isReady(): Promise<boolean> {
const url = new URL(this.baseUrl);
const response = await fetch(url.toString());
const respJson = await response.json();
return respJson.isReady;
}
}
describe('HttpNode', () => {
let httpNode: HttpNode;
beforeEach(() => {
httpNode = new HttpNode(TEST_URL);
});
afterEach(() => {
jest.clearAllMocks();
});
describe('isReady', () => {
it.each([true, false])('should return %s when the node is ready', async () => {
const response = { isReady: true };
setFetchMock(response);
const result = await httpNode.isReady();
expect(fetch).toHaveBeenCalledWith(TEST_URL);
expect(result).toBe(true);
});
});
});
But when I remove the // @ts-ignore
line I get the following error:
How would I correctly type this?
This is the relevant part of package.json:
{
...
"jest": {
"preset": "ts-jest/presets/default-esm",
"moduleNameMapper": {
"^(\\.{1,2}/.*)\\.js$": "$1"
},
"testRegex": "./src/.*\\.test\\.ts$",
"rootDir": "./src"
},
"dependencies": {
...
"tslib": "^2.4.0"
},
"devDependencies": {
"@jest/globals": "^29.5.0",
"@types/jest": "^29.5.0",
"@types/node": "^18.7.23",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.1",
"typescript": "^5.0.4"
},
...
}
All the examples on the internet I could find seem to be outdated. Thank you
I managed to get around the issue. This is the relevant part:
const setFetchMock = (response: any): void => {
global.fetch = jest
.fn<typeof global.fetch>()
.mockImplementation((_input: RequestInfo | URL, _init?: RequestInit | undefined) => {
return Promise.resolve({
ok: true,
json: () => response,
} as Response);
});
};
Here is the full test.