开玩笑:监视正在测试的模块中的其他功能

Sup*_*pen 4 unit-testing jestjs

我正在尝试使用 jest 测试模块。在模块中,我有一个函数作为其他两个函数的前端,并根据其参数委托给它们。我试图弄清楚这些函数是否确实被调用了。

我尝试过使用间谍功能,但它从未被调用。相反,实际的函数被调用,绕过了我的间谍。

我发现的所有模拟和间谍示例都涉及模拟和监视另一个模块而不是正在测试的模块,但在这种情况下,我试图监视正在测试的模块中的函数。这可能吗?有一个更好的方法吗?

示例代码:

// funcs.js

const decide = obj => {
  if (obj.a !== undefined) {
    return funcA(obj);
  } else {
    return funcB(obj);
  }
};

const funcA = obj => obj.a;
const funcB = obj => obj.b;

export { decide, funcA, funcB };
Run Code Online (Sandbox Code Playgroud)
// funcs.test.js

import * as fns from "./funcs";

describe("decide", () => {
  it("should delegate to 'funcA' when the parameter has an 'a' property", () => {
    const spy = jest.spyOn(fns, "funcA");
    fns.decide({ a: "Cake" });
    expect(spy).toHaveBeenCalled(); // Error! Number of calls: 0
  });
});
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 5

无法监视或模拟在定义的同一 ES 模块中调用的函数。

这对于 CommonJS 模块是可能的,但前提是函数始终被称为方法:

exports.decide = obj => {
  ...
  exports.funcA(obj);
  ...
};

exports.funcA = obj => obj.a;
Run Code Online (Sandbox Code Playgroud)

可以将这个配方应用于 ES 模块,但这会放弃它们的好处:

const exports = {};
export default exports;

// same as CommonJS
Run Code Online (Sandbox Code Playgroud)

funcA出于funcB可测试性的目的,并且应该被移动到单独的模块并被监视或嘲笑jest.mock,或者所有它们应该作为一个单元进行测试。