Typescript 和 Jest:避免模拟函数上的类型错误

新手上路,请多包涵

当想用 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’。

axios.get 的 typedef 正确地不包括 mockReturnValueOnce 属性。我们可以通过将 axios.get 包装为 Object(axios.get) 来强制 Typescript 将其视为对象文字,但是:

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

原文由 duncanhall 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 727
2 个回答

从 ts-jest 27.0 mocked from ts-jest 开始,将在 28.0 中弃用和删除,您可以在官方 文档 中查看。所以请改用 mocked 来自 jest 。这是 文档

从 ts-jest 模拟将在 28.0 中被弃用和删除

所以对于你的例子:

 import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';

jest.mock('axios');

// OPTION - 1
const mockedAxios = jest.mocked(axios, true)
// your original `it` block
it('Calls the GET method as expected', async () => {
  const expectedResult: string = 'result';

  mockedAxios.mockReturnValueOnce({ data: expectedResult });
  const result = await myModuleThatCallsAxios.makeGetRequest();

  expect(mockedAxios.get).toHaveBeenCalled();
  expect(result).toBe(expectedResult);
});

原文由 Melchia 发布,翻译遵循 CC BY-SA 4.0 许可协议

添加这行代码 const mockedAxios = axios as jest.Mocked<typeof axios> 。然后使用 mockedAxios 调用 mockReturnValueOnce。使用您的代码,应该这样做:

 import myModuleThatCallsAxios from '../myModule';
import axios from 'axios';

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

it('Calls the GET method as expected', async () => {
  const expectedResult: string = 'result';

  mockedAxios.get.mockReturnValueOnce({ data: expectedResult });
  const result = await myModuleThatCallsAxios.makeGetRequest();

  expect(mockedAxios.get).toHaveBeenCalled();
  expect(result).toBe(expectedResult);
});

原文由 hutabalian 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题