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

时间:2020-05-30 18:16:52

标签: unit-testing jestjs

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

我尝试使用间谍功能,但从未调用过。而是调用实际功能,绕过我的间谍。

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

示例代码:

// 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 };
// 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
  });
});

1 个答案:

答案 0 :(得分:1)

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

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

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

exports.funcA = obj => obj.a;

可以在ES模块中采用此配方,但这会放弃它们的好处:

const exports = {};
export default exports;

// same as CommonJS

funcAfuncB应该出于可测试性目的而移至单独的模块,并用jest.mock进行监视或嘲笑,或者应将它们全部作为一个单元进行测试。