我有一个打字稿模块,其中包含我正在尝试用玩笑测试的功能。我尝试测试的函数使用与该函数在同一模块中定义的打字稿类。两者均已出口。
我正在尝试模拟该类,但模拟的类没有被使用。正在使用被测文件中的原始版本。
免责声明:这是为了简洁起见而设计的示例,但与我正在使用的代码库的设计方式非常相似。
这是代码:
// mock.ts
export class Foo {
bar(): string {
return 'Original Foo.bar';
}
}
export function fubar() {
return new Foo().bar();
}
// mock.test.ts
import { expect, jest, test } from '@jest/globals';
import { fubar } from './mock';
jest.mock('./mock.ts', () => {
return {
...(jest.requireActual('./mock') as Object),
Foo: {
bar: jest.fn().mockImplementation(() => {
return 'Mocked Foo.bar';
})
}
};
});
describe('Mock Testing', () => {
test('Test if mocked Foo class works', () => {
const result = fubar();
expect(fubar()).toBe('Mocked Foo.bar');
});
});
我的测试输出是:
Expected: "Mocked Foo.bar"
Received: "Original Foo.bar"
16 | test('Test if mocked Foo class works', () => {
17 | const result = fubar();
> 18 | expect(fubar()).toBe('Mocked Foo.bar');
| ^
19 | });
20 | });
21 |
显然,我没有正确设置我的模拟,但是笑话文档似乎很简单地说明了如何在打字稿中执行此操作和/或如何处理单个模块导出多个函数/类而您不导出的情况想要嘲笑一切。
经过一番惊愕之后,事实证明这是不可能实现的。更准确地说,在我的示例中,尽管 Foo 在我的测试脚本上下文中被模拟,但 fubar 看到的 Foo 副本是未模拟的版本。唯一的解决方案是将 Foo 移动到不同的模块/文件。
这对我有用:
import MyClass from "mymodule";
const myMockObject = {
myFunction: jest.fn()
}
jest.mock("mymodule", () => {
const originalModule = jest.requireActual("mymodule");
//Mock the default export and named export 'foo'
return {
__esModule: true,
...(originalModule as any),
MyClass: jest.fn().mockImplementation(() => {
return myMockObject;
}),
};
});