我们正在将一个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
函数。