开玩笑的模拟节点模块不能与打字稿一起使用

时间:2019-09-04 12:20:07

标签: typescript unit-testing mocking jestjs ts-jest

我尝试模拟来自npm的模块uuid/v4。 为此,我创建了一个由jest建议的模拟文件夹:https://jestjs.io/docs/en/manual-mocks

我的文件夹结构:

├──__mocks__ 
|  └──uuid
|       └──v4.ts
├──src
│   └──__tests__
│   └── ...
├──node_modules

模拟节点模块文件 v4.ts

module.exports = jest.fn();

当我尝试在测试文件中导入uuid / v4时,玩笑通常应该导入该模拟,并且我应该能够使用它。

这是我的测试文件:

import uuidv4 from 'uuid/v4';

it('should create a job', () => {
    const jobId = 'fake-job-id';
    uuidv4.mockReturnValue(jobId); 
    ...
}

不幸的是,模拟导入似乎无法正常工作,因为我无法添加jest提供的mockReturnValue,并且出现以下打字错误: property 'mockReturnValue' does not exist on type v4. ts(2339)

您是否知道我该如何解决?预先感谢。

1 个答案:

答案 0 :(得分:2)

处理这种情况的一种常见方法是自动模拟测试中的模块,然后通过使用jest.Mocked告诉TypeScript模块是自动模拟的:

jest.mock('uuid/v4');  // <= auto-mock uuid/v4

import uuidv4 from 'uuid/v4';
const mocked = uuidv4 as jest.Mocked<typeof uuidv4>;  // <= tell TypeScript it's an auto-mock

test('hi', () => {
  mocked.mockReturnValue('mocked result');  // <= use the properly typed mock
  expect(uuidv4()).toBe('mocked result');  // Success!
})

不幸的是,uuid/v4的键入似乎不适用于这种方法。

作为解决方法,您可以使用类型断言:

jest.mock('uuid/v4');  // <= auto-mock uuid/v4

import uuidv4 from 'uuid/v4';

test('hi', () => {
  (uuidv4 as jest.Mock).mockReturnValue('mocked result');  // <= use a type assertion
  expect(uuidv4()).toBe('mocked result');  // Success!
})