Jestjs 为什么第二个Jest模拟函数从未被调用?

Jestjs 为什么第二个Jest模拟函数从未被调用?,jestjs,ts-jest,Jestjs,Ts Jest,我正在模仿navigator函数来实现简单的剪贴板功能。以下是相关代码: // FUNCTION /** * Adds a click event to the button which will save a string to the navigator clipboard. Checks for * clipboard permissions before copying. */ function loader(): void { async function copyUrl

我正在模仿
navigator
函数来实现简单的剪贴板功能。以下是相关代码:

// FUNCTION

/**
 * Adds a click event to the button which will save a string to the navigator clipboard. Checks for
 * clipboard permissions before copying.
 */

function loader(): void {
  async function copyUrl(): Promise<void> {
    const permission = await navigator.permissions.query({ name: "clipboard-write" });
    if (permission.state == "granted" || permission.state == "prompt" ) {
      await navigator.clipboard.writeText("the url");
    } else {
      console.error('Permission not supported');
    }
  }

  const button = document.querySelector('button') as HTMLElement;
  button.addEventListener('click', async () => {
    await copyUrl();
  });
}

现在第一个断言
expect(navigator.permissions.query)失败。toHaveBeenCalledTimes(1)
with

预期呼叫数:1收到呼叫数:0

通过上述添加,我还将断言更改为:

expect(navigator.clipboard.writeText).toHaveBeenCalledWith('the url');
expect(navigator.clipboard.writeText).toHaveBeenCalledTimes(2);
expect(navigator.permissions.query).toHaveBeenCalledTimes(1);
。。。在第二个断言中失败,因为它预期有2个调用,但只收到1个

我一直在VSCode开发容器中进行测试,并尝试使用扩展名
firsttris.VSCode jest runner
来调试测试。通过
loader
函数中的断点,我可以看到每一行都能在我的模型中完美地执行,但在调试结束时仍然失败

我甚至更改了mock
navigator.permissions.query
函数以返回
{state:'denied'}
。无论是运行还是调试,它都没有满足权限检查的要求,并按预期向控制台发送了一个错误,但在
expect(navigator.permissions.query).toHaveBeenCalledTimes(1)
(前面添加了
writeText
调用)测试仍然失败

在我看来,在第一次调用mock函数之后,其他函数就不起作用了

我错过什么了吗?发送帮助,请笑

编辑

使用中的
jest.spyOn
也有同样的问题


使用带有
expect.assertions(n)
断言的异步测试仍然会产生完全相同的问题。

看看,也许你会从中找到一些灵感。我认为问题在于异步,而您的测试不是异步的。@alextrastero我已经详细地研究了这个答案。同样的问题。在使用
expect.assertions
发布之前,也在异步测试中进行了尝试,这是相同的问题。无论如何,加载程序是同步的,所有的承诺都在等待。
// FUNCTION

// ...
async function copyUrl(): Promise<void> {
  
  // add this
  await navigator.clipboard.writeText('the url');

  // keep the rest still
  const permission = await navigator.permissions.query({ name: "clipboard-write" });
  // ...

}

expect(navigator.clipboard.writeText).toHaveBeenCalledWith('the url');
expect(navigator.clipboard.writeText).toHaveBeenCalledTimes(2);
expect(navigator.permissions.query).toHaveBeenCalledTimes(1);