使用 Typescript 从 Jest 手动模拟导入函数 [英] Import function from a Jest manual mock with Typescript

查看:20
本文介绍了使用 Typescript 从 Jest 手动模拟导入函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Typescript 项目中使用 Jest 创建一个自定义模拟(ES6 类).模拟创建结束导出一些 mock.fn() 以便它们可以在测试套件中被监视.

I'm creating a custom mock (of an ES6 class) with Jest in a Typescript project. The mock creates end exports a few mock.fn() so that they could be spied on in the test suite.

示例可能是 Jest 文档中的官方示例 (https://jestjs.io/docs/en/es6-class-mocks#manual-mock).SoundPlayer 类已经被模拟,因为它是它唯一的方法 playSoundFile.该方法使用 jest.fn() 模拟,该代码被导出以用于测试.

An example could be the official one from the Jest documentation (https://jestjs.io/docs/en/es6-class-mocks#manual-mock). There the SoundPlayer class has been mocked, as it is its only method playSoundFile. The method is mocked using a jest.fn(), which is exported to be used in tests.

// soundPlayer.ts
export default class SoundPlayer {
  foo: string = 'bar';

  playSoundFile(filename: string) {
    console.log(`Playing sound file ${filename}`);
  }
}

// __mocks__/soundPlayer.ts
export const mockPlaySoundFile = jest.fn();

const mock = jest.fn().mockImplementation(() => {
  return { playSoundFile: mockPlaySoundFile };
});

export default mock;

// __tests__/soundPlayer.ts
import SoundPlayer, { mockPlaySoundFile } from '../soundPlayer';

jest.mock('../soundPlayer');

beforeEach(() => {
  mockPlaySoundFile.mockClear();
});

it('is called with filename', () => {
  const filename = 'song.mp3';
  const soundPlayer = new SoundPlayer();
  soundPlayer.playSoundFile(filename);

  expect(mockPlaySoundFile).toBeCalledWith(filename);
});

测试按预期工作,但 TS 在尝试导入模拟的 mockPlaySoundFile 函数时通知错误(这对我来说很有意义).那是因为,很明显,soundPlayer.ts 中不存在 mockPlaySoundFile.但是由于 jest.mock('../soundPlayer'); 模拟是在引擎盖下导入的,因此导出确实存在.

The test works as expected, but TS notifies an error (which kind of makes sense to me) when trying to import the mocked mockPlaySoundFile function. That is because, obviously, mockPlaySoundFile doesn't exist in soundPlayer.ts. But because of jest.mock('../soundPlayer'); the mock is imported under the hood, therefore the export does exist.

有没有办法通知 TS 在这种情况下查看模拟?

Is there a way to inform TS to look at the mocks in cases like this?

推荐答案

解决这个问题的最简单方法是使用 ts-jestmocked() 助手.助手将确保您可以访问模拟测试方法.__tests__/soundPlayer.ts 将如下所示:

The easiest way to fix this is to use ts-jest's mocked() helper. The helper will make sure you have access to the mock test methods. __tests__/soundPlayer.ts would then look as follows:

// __tests__/soundPlayer.ts
import { mocked } from "ts-jest/utils";
import SoundPlayer from '../soundPlayer';

jest.mock('../soundPlayer');

const soundPlayer = mocked(new SoundPlayer());

beforeEach(() => {
  soundPlayer.playSoundFile.mockClear();
});

it('is called with filename', () => {
  const filename = 'song.mp3';

  soundPlayer.playSoundFile(filename);

  expect(soundPlayer.playSoundFile).toBeCalledWith(filename);
});

如果您真的想包含 mockPlaySoundFile,您可以通过告诉 Typescript 编译器抑制导入错误来实现:

If you really want to include mockPlaySoundFile you could do it by telling the Typescript compiler to suppresses the import error:

// @ts-ignore
import { mockPlaySoundFile } from '../soundPlayer';

另外,在这里查看我的 repo 中的示例:https://github.com/tbinna/ts-jest-mock-examples,特别是你的 soundPlayer 示例:https://github.com/tbinna/ts-jest-mock-examples/tree/master/sound-player

Also, have a look at the example in my repo here: https://github.com/tbinna/ts-jest-mock-examples, in particular, your soundPlayer example: https://github.com/tbinna/ts-jest-mock-examples/tree/master/sound-player

这篇关于使用 Typescript 从 Jest 手动模拟导入函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆