Javascript Jest-使用spyOn函数时,请确保未调用Spyed函数

Javascript Jest-使用spyOn函数时,请确保未调用Spyed函数,javascript,angular,jestjs,Javascript,Angular,Jestjs,从Jest notes:注意:默认情况下,Jest.spyOn还调用spied方法。 在我的角分量中 ngAfterViewInit(): void { this.offsetPopoverPosition(); } 在我的规范中: it('ngAfterViewInit() method should call offsetPopoverPosition() method', () => { const mockListener = jest.spyOn(cmp, 'off

从Jest notes:注意:默认情况下,Jest.spyOn还调用spied方法。

在我的角分量中

ngAfterViewInit(): void {
  this.offsetPopoverPosition();
}
在我的规范中:

it('ngAfterViewInit() method should call offsetPopoverPosition() method', () => {
    const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
    const spy = mockListener.mockImplementation(() => {
      console.log('in the mock');
    });

    cmp.ngAfterViewInit();
    expect(spy).toHaveBeenCalled();
  });
简单。但仍在调用原始函数。 我查看了Jest 23.x文档:

互联网上的例子很少,但我无法阻止jest调用原始的
offsetPopoverPosition()
方法

有什么想法吗

我正在交叉链接到Jest github问题,由于某种原因,该问题没有得到解决


我想我在这里也遇到了同样的问题,所以也许我们可以互相帮助。 我有3个文件

  • 一个名为dbManager.js的
  • 另一个名为mssqlPool.js
  • 然后是测试文件dbManager.test.js

测试的文件位于/src/db文件夹中

测试文件位于/test/db文件夹中(基本上复制了src文件夹树)

我想模拟mssqlPool.js

module.exports = {
  mssqlPool: async config => {
    // actual connection with an await (in case it matters)
  }
}
下面是DBManger,它是一个具有构造函数的类:

const { mssqlPool } = require('./mssqlPool');

module.exports = class DBManager {
  constructor(config) {}
}

async initPool() {
    if (global.DB_TYPE === 'mssql') {
      this.pool = await mssqlPool(this.config);
      return true;
    }}


我已经将我的mssqlPool文件从
module.exports=config=>{}
更改为
module.exports={mssqlPool:config=>{}}
为了能够使用spyOn

,根据我的经验,问题是您正在重置原始模拟的意图。当您创建spy时,它有自己的实现,通过使用mockImplementation覆盖它,我体验到了您描述的场景-相反,请尝试以下方法:

cmp.offsetPopoverPosition = jest.fn().mockImplementation(() => {
      console.log('in the mock');
    });
const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
// ... do work
expect(mockListener).toHaveBeenCalled[Times,With]()
此外,这还假设
cmp
是组件的实例,而不仅仅是它的定义参考


编辑:请注意,在您正在测试的组件内部模拟一个消息函数是一种错误的单元测试方法。不要测试与
sameComponent.method
的通信-测试链式方法在被测试组件之外使用的任何消息传递-使用简短的问题内容,请忽略我给出的测试方法建议,如果它的阅读内容与单元测试设计无关

组件构造函数中的
offsetPopoverPosition
是否绑定到
this
?不,它仅在ngAfterViewInit中调用…啊,看起来
cmp
是一个实例,因此它无论如何都不会有什么不同。从我所看到的代码来看,它看起来应该可以工作。(JonathanHolvey在github链接中的代码不起作用的原因是,
processVisit
直接调用了
saveVisit
,因此模仿模块导出来进行
saveVisit
没有任何效果……这不适用于您的代码,因为我看到的两个函数都是类方法)Hi Valentin,这不是stackexchange站点的工作方式,它是一个问答站点,因此请仅提供答案。如果您的答案应该包含真实的答案,请标记它。@Valentin_Dissais-由于我正在开发的其他功能,我不得不暂时停止对这个问题的调查,但我强烈怀疑jest
.mockImplementation()
方法不起作用-它不会阻止对spied函数的调用。@codeepic这很奇怪,因为它在我测试的另一个微服务上工作得非常好,这与您完全一样,它应该可以工作,但它不能
  jest.spyOn(mssqlPool, 'mssqlPool').mockImplementation(() => Promise.resolve());
cmp.offsetPopoverPosition = jest.fn().mockImplementation(() => {
      console.log('in the mock');
    });
const mockListener = jest.spyOn(cmp, 'offsetPopoverPosition');
// ... do work
expect(mockListener).toHaveBeenCalled[Times,With]()