【问题标题】:Is it possible to mock a function called from inside module in jest?是否可以开玩笑地模拟从模块内部调用的函数?
【发布时间】:2021-10-31 14:27:14
【问题描述】:

我有一个带有两个函数的 TypeScript 模块:foo() 调用 bar()。我想模拟 bar() 并从单元测试中调用 foo() 。我试过这个:

foo.ts:

export function bar(){
  throw 'not implemented'
}

export function foo(){
  return bar();
}

foo.test.ts:

import * as foo from './foo'

test('TODO', () => {
  jest.spyOn(foo, 'bar').mockReturnValue('quux')
  expect(foo.foo()).toBe('quux')
});

但我得到了一个错误:

 FAIL  ./foo.test.ts
  ✕ TODO (4 ms)

  ● TODO

    thrown: "not implemented"

      1 | import * as foo from './foo'
      2 |
    > 3 | test('TODO', () => {
        | ^
      4 |   jest.spyOn(foo, 'bar').mockReturnValue('quux')
      5 |   expect(foo.foo()).toBe('quux')
      6 | });

      at Object.<anonymous> (foo.test.ts:3:1)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)

似乎 foo() 以某种方式绕过了模拟。我怎样才能让它使用模拟而不是真正的 bar()?

【问题讨论】:

    标签: typescript jestjs mocking


    【解决方案1】:

    要修复此更改 foo() 以调用 exports.bar() 而不是 bar():

    export function foo(){
      return exports.bar();
    }
    
    您的示例中的

    foo() 绕过了模拟,因为有两个命名空间:模块和导出对象。当 bar() 的引用被解析时,JavaScript 和 TypeScript 在模块命名空间中搜索它,但 Jest 只能监视导出对象,不能更改模块的内容。

    一种可能的解决方案是通过导出对象显式查找要模拟的标识符,如上所示。

    我在这里找到了这种方法:https://medium.com/welldone-software/jest-how-to-mock-a-function-call-inside-a-module-21c05c57a39f#576f

    【讨论】:

      【解决方案2】:

      试试这个重构:

      foo.ts:

      const fn = {
        bar(): unknown | void {
          throw "not implemented";
        },
      
        foo() {
          return fn.bar();
        },
      };
      
      export default fn
      

      foo.test.ts:

      import functionsUnderTest from "./foo";
      
      beforeEach(() => {
        jest.spyOn(functionsUnderTest, "bar").mockReturnValue("quux");
      });
      
      test("TODO", () => {
        expect(functionsUnderTest.foo()).toBe("quux");
      });
      

      命名空间问题通过这种方式解决

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-05
        • 1970-01-01
        • 2023-02-03
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 2018-07-25
        • 1970-01-01
        相关资源
        最近更新 更多