Jest测试,在第一次调用时调用实际实现,模拟其余部分



我们正在将一个repo从sinon stub移到jest,而我在这个mock上遇到了问题。我想做的是在第一次调用时调用实际的实现,然后模拟其余的调用。这个函数是递归的,所以我们希望第一个调用调用实际实现,然后模拟递归调用。

在西农,它是这样做的

const stub = sandbox.stub(instance, 'function');
stub
.onFirstCall()
.callsFake(stub.wrappedMethod)
.callsFake((args) => args);

我想做一些类似的事情,但在joy-spy或mock实例上找不到实际实现。难道这根本不可能吗?

const spy = jest.spyOn(instance, 'function');
spy
.mockImplementationOnce(spy.mock.actual) // ???
.mockImplementation((args) => args);

为什么不能做如下类似的事情?

const spy = jest.spyOn(instance, 'function');
spy
.mockImplementationOnce(() => originalInstanceFunction())
.mockImplementation((args) => args);

下面是一个示例实现-注意必须存储对原始实例函数的引用

const original = {
func: (args) => { console.log(`original ${args}`)} 
};

describe('test', () => {
it('should call original then mock', () => {
const originalFunction = original.func;
const spy = jest.spyOn(original, 'func');
spy.mockImplementationOnce((args) => originalFunction(args))
.mockImplementation((args) => console.log(`mock ${args}`));

original.func('test-args');
original.func('test-args');
expect(spy).toBeCalledTimes(2);
});
});

输出:

console.log
original test-args
at originalFunction (test.test.js:2:28)
console.log
mock test-args
at Object.spy.mockImplementationOnce.mockImplementation.args (test.test.js:12:42)

要使用模拟库执行此操作,请使用jest.requireActual()。复制指南中的示例:

jest.mock('node-fetch');
const fetch = jest.requireActual('node-fetch');

这允许您在正在测试的代码中模拟fetch库,但在测试本身中使用真正的fetch函数。

最新更新