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

查看:47
本文介绍了使用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()进行模拟,该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);
});

测试按预期方式工作,但是在尝试导入模拟的mockPlaySoundFile函数时,TS会通知错误(这对我来说有意义).这是因为显然mockPlaySoundFilesoundPlayer.ts中不存在.但是由于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?

推荐答案

最简单的解决方法是使用

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';

另外,请在此处查看我的回购中的示例: https://github.com/tbinna/ts-jest-mock-examples ,特别是您的soundPlayer示例:

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天全站免登陆