首页 > 解决方案 > Jest spyOn 无法识别函数调用

问题描述

我有一个具有两个功能的节点模块:

authenticate()signIn()

authenticatesignIn作为辅助函数的调用都从模块中导出,如下所示:

module.exports = { authenticate, signIn };

我正在遵循针对此处找到的类似问题的建议: 预期的 spyOn 函数将被称为 Jest

在我的测试结果中注销模块的内容以确认两种方法都存在:

      {
        authenticate: [AsyncFunction: authenticate],
        signIn: [AsyncFunction: signIn]
      }

我监视signIn何时authentication正在测试以确保它被调用,并且我知道它被调用是因为从signIn注销到控制台的消息。我希望这个测试能够通过,但是它没有说当预期 >=1 时有 0 个调用。

const auth = require("./authenticate");

test("should signIn", async () => {
  console.log(auth);
  const signInSpy = jest.spyOn(auth, "signIn").mockResolvedValue({ access_token: "123" });
  await auth.authenticate();
  expect(signInSpy).toBeCalled();
});

我假设我设置不正确,因为调用auth.authenticate()确实调用了auth模块signIn,但我不知道它是什么。

标签: javascriptnode.jsjestjs

解决方案


如果您的代码authenticate.js看起来像这样,直接调用身份验证signIn,Jest 将不会模拟该值,因为它是对原始函数的引用,而不是导出对象的属性。

// Doesn't work
const signIn = () => console.log("Signed in");
// `signIn` will never be anything other than the function above
const authenticate = () => signIn();

module.exports = {
  authenticate,
  signIn
};

如果您module.exports直接或通过 using 使用该对象,this您将能够在您的测试中从 Jest 访问间谍版本。

// Works
module.exports.signIn = () => console.log("Signed in");
module.exports.authenticate = () => module.exports.signIn();
// Also works
module.exports = {
  authenticate: function () {
    this.signIn();
  },
  signIn: () => console.log("Signed in")
};

如果这些解决方案不适用于您的原始代码,您可能希望部分模拟 authenticate.js 模块,或者将您的函数分离到不同的文件中。


推荐阅读