首页 > 解决方案 > JEST 期望函数在 setTimeout 内被调用

问题描述

我有一个简单的函数,它在 setTimeout 中打开一个新窗口,并想测试打开的窗口是否被调用。

export function foo() {
     setTimeout(() => {
        window.open('http://google.com');
    }, 0);
 }

describe('foo', () => {
    beforeEach(() => {
        jest.useFakeTimers();
        global.open = jest.fn();
    });

    it('calls open', () => {
        foo();

        expect(setTimeout).toHaveBeenCalledTimes(1);
        expect(global.open).toBeCalled(); //FAILING
    });
});

目前我的期望是“预期的模拟函数已被调用”。当我从函数中删除 setTimeout 时,window.open 的模拟看起来工作正常,因为测试通过了。

只是想知道是否有人可以引导我朝着正确的方向前进。提前致谢。

标签: javascriptunit-testingjestjs

解决方案


计时器不仅应该是伪造的,还应该根据https://jestjs.io/docs/en/timer-mocksjest.runAllTimers();上的文档运行,如下例所示:

test('calls the callback after 1 second', () => {
  const timerGame = require('../timerGame');
  const callback = jest.fn();
  jest.useFakeTimers();

  timerGame(callback);

  // At this point in time, the callback should not have been called yet
  expect(callback).not.toBeCalled();

  // Fast-forward until all timers have been executed
  jest.runAllTimers();

  // Now our callback should have been called!
  expect(callback).toBeCalled();
  expect(callback).toHaveBeenCalledTimes(1);
});

推荐阅读