当想要使用 Jest 模拟外部模块时,我们可以使用该jest.mock()方法自动模拟模块上的函数。
jest.mock()
然后,我们可以根据需要操作和查询模拟模块上的模拟函数。
例如,考虑以下模拟 axios 模块的例子:
import myModuleThatCallsAxios from '../myModule'; import axios from 'axios'; jest.mock('axios'); it('Calls the GET method as expected', async () => { const expectedResult: string = 'result'; axios.get.mockReturnValueOnce({ data: expectedResult }); const result = await myModuleThatCallsAxios.makeGetRequest(); expect(axios.get).toHaveBeenCalled(); expect(result).toBe(expectedResult); });
上述代码在 Jest 中可以正常运行,但会抛出 Typescript 错误:
类型“(url: string, config?: AxiosRequestConfig | undefined) => AxiosPromise”上不存在属性“mockReturnValueOnce”。
正确的 typedefaxios.get不包含mockReturnValueOnce属性。我们可以强制 Typescript 将axios.get其包装为 Object 文字Object(axios.get),但是:
axios.get
mockReturnValueOnce
Object(axios.get)
在保持类型安全的同时模拟函数的惯用方法是什么?
要像axios在 Jest 中一样模拟外部模块,同时保持 TypeScript 中的类型安全,您可以使用 Jest 的类型断言以及内置的 TypeScript 实用程序来获得更好的类型支持。以下是您可以以惯用的方式实现这一点的方法:
axios
jest.mock
jest.MockedFunction
您可以按照以下方法将上述步骤应用到您的示例中:
import myModuleThatCallsAxios from '../myModule'; import axios from 'axios'; // Mock axios module jest.mock('axios'); // Define axios.get as a mocked function with correct type const mockedAxios = axios as jest.Mocked<typeof axios>; it('Calls the GET method as expected', async () => { const expectedResult: string = 'result'; // Mock the return value of axios.get mockedAxios.get.mockResolvedValueOnce({ data: expectedResult }); // Call the function in your module that uses axios.get const result = await myModuleThatCallsAxios.makeGetRequest(); // Assert the axios.get was called and the result is as expected expect(mockedAxios.get).toHaveBeenCalled(); expect(result).toBe(expectedResult); });
jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;
这告诉 TypeScriptaxios应该将其视为一个模拟,其所有方法都被模拟。
mockedAxios.get.mockResolvedValueOnce({ data: expectedResult });
Jest 提供实用类型来确保模拟类型安全。在本例中,jest.Mocked<typeof axios>用于将其类型化axios为其自身的模拟版本。
jest.Mocked<typeof axios>
mockResolvedValueOnce
jest.Mocked
使用这种方法可确保您的模拟是类型安全的,并且您在编写测试时可以获得 TypeScript 的类型检查和自动完成功能的好处。