我想为特定测试模拟模块和函数。我有以下内容:
test("my test", () => {
jest.mock("some_module")
some_module.some_function = jest.fn();
...
})
test("another test", () => {
...
});
我的问题是,当测试完成时,两个模拟都将被“取消设置”,以便我可以在下一个测试中使用真正的实现吗?还是我必须自己明确删除所有模拟?
答案 0 :(得分:2)
测试完成后,所有模拟都将被“取消设置”吗?
Jest测试是在测试文件的基础上进行沙箱测试的,因此通常在该文件中的所有测试运行之后,所有模拟都将被还原。
但是,您在那做什么:some_module.some_function = jest.fn();
不是通过Jest的模拟机制进行模拟,而是猴子修补了导入的函数。这将不会被Jest删除。
您应该改为执行以下操作:
import { some_function } from 'some-module-path';
jest.mock('some-module-path');
test('my test', () => {
...
expect(some_function).toHaveBeenCalled(); // e.g.
}
更新:
在评论中进行讨论之后,下面是一个在Jest中安全地进行简单猴子补丁的示例,以便将其还原到同一文件中以供后续测试:
// foo.js -----------------------------------
export const foo = () => 'real foo';
// bar.js -----------------------------------
import { foo } from './foo';
export const bar = () => foo();
// bar.test.js ------------------------------
import { bar } from './bar';
import * as fooModule from './foo';
describe('with mocked foo', () => {
let originalFoo;
beforeAll(() => {
// patch it!
originalFoo = fooModule.foo;
fooModule.foo = () => 'mocked foo';
});
afterAll(() => {
// put it back again!
fooModule.foo = originalFoo;
});
test('mocked return value from foo()', () => {
expect(bar()).toEqual('mocked foo');
});
});
describe('with real foo', () => {
test('expect real return value from foo()', () => {
expect(bar()).toEqual('real foo');
});
});
更新2:
另一种选择是,您可以模拟依赖项,并通过jest.requireActual
临时使用原始实现:
import { bar } from './bar';
import { foo } from './foo';
jest.mock('./foo');
foo.mockReturnValue('mocked foo');
const fooModule = jest.requireActual('./foo')
test('mocked return value from foo()', () => {
expect(bar()).toEqual('mocked foo');
});
test('real return value from foo()', () => {
foo.mockImplementation(fooModule.foo);
expect(bar()).toEqual('real foo');
});