避免使用mocked typescript导入

Bri*_*ian 7 typescript jestjs

我正在导入一个模拟函数,但由于Typescript似乎不知道Jest将导入更改为模拟,我必须先导入导入的函数,然后再使用模拟方法等mockReturnValue.

jest.mock('../myImport');
import { thisFunctionIsMocked } from '../myImport'

/* ... */

(<Mock<any>>thisFunctionIsMocked).mockReturnValue(42);
Run Code Online (Sandbox Code Playgroud)

如果我不转换导入,Typescript声称mock函数方法不存在.有一个更好的方法吗?

lob*_*ati 7

我一直在寻找相同的。不幸的是,关于如何处理这个问题似乎并不多。然而,一些替代方案。

1)您已经在做的事情的语法略有不同:

(thisFunctionIsMocked as jest.Mock).mockReturnValue(42);
Run Code Online (Sandbox Code Playgroud)

2)require改为使用并投射到那里:

const thisFunctionIsMocked = require('../myImport') as jest.Mock;
Run Code Online (Sandbox Code Playgroud)

更新:

ts-jest现在有一个可以使用的mocked助手。引用模拟导入时仍然需要使用它,但这意味着原始源的类型签名不会丢失:

import { mocked } from 'ts-jest/utils';

test('direct', () => {
  foo.name();
  expect(mocked(foo.name).mock.calls).toHaveLength(1);
});
Run Code Online (Sandbox Code Playgroud)


Nit*_*mer -1

可以使用模块扩充,但如果像这样导出函数则不能使用:

export function thisFunctionIsMocked() { .... }
Run Code Online (Sandbox Code Playgroud)

这是因为您只能添加类型,而不能更改现有类型。
但如果你像这样导出:

export interface MyMockedFunction {
    (): void;
}

export const thisFunctionIsMocked = function() { ... } as MyMockedFunction;
Run Code Online (Sandbox Code Playgroud)

然后你应该能够增强它:

jest.mock('../myImport');
import { thisFunctionIsMocked } from '../myImport'

declare module "../myImport" {
    interface MyMockedFunction {
        mockReturnValue(value: number): any;
    }
}

thisFunctionIsMocked.mockReturnValue(42);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的建议。我不知道模块增强。但说实话,如果要在这个和强制转换之间进行选择,我会选择强制转换。我正在努力减少编写测试所需的开销和视觉混乱。理想情况下,在调用“jest.mock”之后,Typescript 会以某种方式知道导入的函数是不同的。也许工具级解决方案是唯一的选择? (4认同)