【问题标题】:Jest testing, call actual implementation on first call, mock the rest开玩笑测试,在第一次调用时调用实际实现,模拟其余部分
【发布时间】:2021-06-16 03:04:52
【问题描述】:

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

在sinon里面是这样子的

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

我想做这样的事情,但在 jest spy 或 mock 实例上找不到实际的实现。这根本不可能吗?

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

【问题讨论】:

  • 您能否提供一些上下文 - 为什么第一个电话应该通过?
  • 函数是递归的,所以我们想测试一下递归调用的调用次数。
  • 为什么?它的递归不是实现细节吗?来电者在乎吗?
  • 我想这可能是一个糟糕的测试,但我现在的目标是让事情顺利进行。
  • 迁移不是摆脱不良测试而不是花时间迁移它们的理想时机吗?

标签: javascript node.js jestjs


【解决方案1】:

要使用模拟库执行此操作,请使用 jest.requireActual()。从the guide复制一个例子:

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

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

【讨论】:

    【解决方案2】:

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

    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)
    

    【讨论】:

    • 不是第一个示例不起作用,因为instance.function间谍?如果是这样,那么将它留在里面就没有什么意义了,而且你当然不应该没有这个警告。
    • 已编辑 - 并非作为工作示例,工作示例是示例实现。
    猜你喜欢
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2018-11-27
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    相关资源
    最近更新 更多