小能豆

Typescript 和 Jest:避免模拟函数出现类型错误

javascript

当想要使用 Jest 模拟外部模块时,我们可以使用该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),但是:

在保持类型安全的同时模拟函数的惯用方法是什么?


阅读 32

收藏
2024-06-05

共1个答案

小能豆

要像axios在 Jest 中一样模拟外部模块,同时保持 TypeScript 中的类型安全,您可以使用 Jest 的类型断言以及内置的 TypeScript 实用程序来获得更好的类型支持。以下是您可以以惯用的方式实现这一点的方法:

循序渐进指南

  1. 模拟模块:用于jest.mock模拟axios模块。
  2. 模拟的类型断言:使用jest.MockedFunction或类型断言来正确处理模拟的类型。
  3. 与 Mock 交互:利用 Jest 提供的类型安全方法。

示例代码

您可以按照以下方法将上述步骤应用到您的示例中:

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

解释

  1. 模拟模块

jest.mock('axios');

  1. 模拟的类型断言

const mockedAxios = axios as jest.Mocked<typeof axios>;

这告诉 TypeScriptaxios应该将其视为一个模拟,其所有方法都被模拟。

  1. 与 Mock 交互

mockedAxios.get.mockResolvedValueOnce({ data: expectedResult });

实用程序类型

Jest 提供实用类型来确保模拟类型安全。在本例中,jest.Mocked<typeof axios>用于将其类型化axios为其自身的模拟版本。

笔记

  • mockResolvedValueOnce:这种方法模拟承诺的解决值,这对于模拟来说很常见axios.get
  • 类型安全:通过使用jest.MockedFunctionjest.Mocked,您可以确保 TypeScript 了解这些函数是模拟,并且您可以获得诸如 、 等方法的自动完成和类型mockReturnValueOnce检查mockResolvedValueOnce

使用这种方法可确保您的模拟是类型安全的,并且您在编写测试时可以获得 TypeScript 的类型检查和自动完成功能的好处。

2024-06-05