使用Typescript从Jest手动模拟导入函数

使用Typescript从Jest手动模拟导入函数,typescript,mocking,jestjs,Typescript,Mocking,Jestjs,我正在一个Typescript项目中使用Jest创建一个自定义模拟(ES6类)。mock创建一些mock.fn()的最终导出,以便在测试套件中监视它们 一个示例可以是Jest文档()中的官方示例。在那里,SoundPlayer类被模拟,因为它是它唯一的方法playSoundFile。使用导出用于测试的jest.fn()模拟该方法 //soundPlayer.ts 导出默认类SoundPlayer{ foo:string='bar'; 播放声音文件(文件名:字符串){ log(`Playing s

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

一个示例可以是Jest文档()中的官方示例。在那里,
SoundPlayer
类被模拟,因为它是它唯一的方法
playSoundFile
。使用导出用于测试的
jest.fn()
模拟该方法

//soundPlayer.ts
导出默认类SoundPlayer{
foo:string='bar';
播放声音文件(文件名:字符串){
log(`Playing sound file${filename}`);
}
}
/\uuuuu mocks\uuuu/soundPlayer.ts
export const mockPlaySoundFile=jest.fn();
const mock=jest.fn().mock实现(()=>{
返回{playSoundFile:mockPlaySoundFile};
});
导出默认模拟;
/\uuuu测试\uuuu/soundPlayer.ts
从“../SoundPlayer”导入SoundPlayer,{mockPlaySoundFile};
jest.mock(“../soundPlayer”);
在每个之前(()=>{
mockPlaySoundFile.mockClear();
});
它('用文件名调用',()=>{
常量文件名='song.mp3';
const soundPlayer=新的soundPlayer();
播放声音文件(文件名);
expect(mockPlaySoundFile).toBeCalledWith(文件名);
});
测试按预期工作,但TS在尝试导入模拟的
mockPlaySoundFile
函数时会通知一个错误(这对我来说是有意义的)。这是因为,
soundPlayer.ts
中显然不存在
mockPlaySoundFile
。但是因为
jest.mock('../soundPlayer')模拟在引擎盖下导入,因此导出确实存在


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

我也有同样的问题,我只有一个解决方法。我的问题是我从节点手动模拟fs

因此,我有一个“fs”的手动模拟,大致如下所示:

const fs = jest.genMockFromModule("fs");

let mockFiles = {};

function __clearMocks(){
    mockFiles = {};
}

module.exports = fs;
import * as fs from 'fs';
import 'fsExtension';
fs.__clearMocks();
很明显,当我的测试用例导入fs时,它将不起作用:

import * as fs from 'fs';
fs.__clearMocks();
要使其正常工作,我创建了以下类型的扩展:

declare module 'fs' {
    export function __clearMocks(): void; 
}
现在我可以修改我的测试用例如下:

const fs = jest.genMockFromModule("fs");

let mockFiles = {};

function __clearMocks(){
    mockFiles = {};
}

module.exports = fs;
import * as fs from 'fs';
import 'fsExtension';
fs.__clearMocks();

希望这对你有帮助

解决此问题的最简单方法是使用的
mocked()
helper。助手将确保您可以访问模拟测试方法<代码>\uuuu测试\uuuu/soundPlayer.ts
将如下所示:

// __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编译器抑制导入错误:

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

另外,请看我的报告中的示例:,特别是您的
soundPlayer
示例:

此线程有许多关于如何执行此操作的好示例:您可以使用ts jest中的
mock
帮助器: