Jest 27:如何为jest.spyOn重置模拟(窗口,“setTimeout”)?

k5hmc34c  于 2023-03-16  发布在  Jest
关注(0)|答案(3)|浏览(267)

我正在将一个项目从jest版本26更新到jest版本27。作为更新的一部分,我必须从setTimeout上的Assert切换到jest.spyOn(window, "setTimeout")上的Assert。
我想全局定义spy并在每次测试前重置它,类似于:

const timeoutSpy = jest.spyOn(window, "setTimeout");
beforeEach(() => {
    jest.resetAllMocks();
});

这段代码并没有像我预期的那样工作。expect(timeoutSpy).toHaveBeenCalledTimes(n)的Assert失败是因为预期的调用数(n)和接收的调用数(0)不匹配。
在每次测试之前重置全局定义的timeoutSpy的正确方法是什么?
谢谢你。

q9rjltbz

q9rjltbz1#

您应该使用jest.restoreAllMocks()。
将所有模拟恢复为原始值。等效于在每个模拟函数上调用.mockRestore()。请注意,jest.restoreAllMocks()仅在使用jest.spyOn创建模拟时有效;其他模拟将需要您手动恢复它们。

flvtvl50

flvtvl502#

读取/不复制

我正在使用:

  • NodeJS 版本16.17.0
  • 国家预防机制8.19.1
  • 笑话

对我来说,唯一有效的解决方案是使用MockXXXOnce,并且不恢复它,特别是使用计时器时,它似乎正在重置模拟,例如

const spySetTimeout = jest.spyOn(global, 'setTimeout')

做一些类似的事情:

spySetTimeout.mockReset() // mockRestore() ...

损坏计时器,或者无论如何原始实现将不再工作
为此我做了

spySetTimeout.mockReturnValueOnce(1000)

只在我需要的it(x, async ()=>{})测试上。
存储函数引用也不起作用,因为至少jestx 1 m2n1x模拟将位于实际函数上

cetgtptt

cetgtptt3#

beforeEach中使用jest.resetAllMocks();就足够了,下面的代码可以证明这一点:

function callTimeout() {
  setTimeout(() => {
    console.log('hello');
  })
}

const timeoutSpy = jest.spyOn(window, 'setTimeout');

describe("test timeout", () => {
  beforeEach(() => {
    jest.resetAllMocks();
  });

  it("test 1", () => {
    callTimeout();
    callTimeout();
    expect(timeoutSpy).toHaveBeenCalledTimes(2);
  })

  it("test 2", () => {
    callTimeout();
    callTimeout();
    expect(timeoutSpy).toHaveBeenCalledTimes(2);
  })
});

我不得不将jest.config.js文件中的testEnvironment属性测试为jsdom,以使window变量工作。但是,您可以将window替换为global,以使其与默认值node一起工作。

相关问题