【问题标题】:NodeJS - Jest unit test setTimeout in process.on callbackNodeJS - process.on 回调中的 Jest 单元测试 setTimeout
【发布时间】:2018-03-11 16:22:03
【问题描述】:

我正在尝试在 process.on('SIGTERM') 回调中使用 Jest 对计时器进行单元测试,但它似乎从未被调用。我正在使用jest.useFakeTimers(),虽然它似乎在一定程度上模拟了setTimeout 调用,但在检查它时它并没有出现在setTimeout.mock 对象中。

我的 index.js 文件:

process.on('SIGTERM', () => {
    console.log('Got SIGTERM');

    setTimeout(() => {
        console.log('Timer was run');
    }, 300);
});

setTimeout(() => {
    console.log('Timer 2 was run');
}, 30000);

和测试文件:

describe('Test process SIGTERM handler', () => {
    test.only('runs timeout', () => {
        jest.useFakeTimers();
        process.exit = jest.fn();

        require('./index.js');

        process.kill(process.pid, 'SIGTERM');

        jest.runAllTimers();

        expect(setTimeout.mock.calls.length).toBe(2);
    });
});

测试失败:

预期值为(使用 ===): 2 已收到: 1 控制台日志输出为:

console.log tmp/index.js:10
    Timer 2 was run

  console.log tmp/index.js:2
    Got SIGTERM

如何让setTimeout 在此处运行?

【问题讨论】:

  • 尝试将 sigterm 更改为 sighup 进行测试。 sigterm 可能会终止该进程。还可以尝试删除计时器 1 并检查控制台日志是否实际上以同步方式工作。

标签: javascript node.js unit-testing jestjs


【解决方案1】:

可以做的是模拟on 方法的进程,以确保您的处理程序将在kill 方法上被调用。

确保调用处理程序的一种方法是模拟 killon

describe('Test process SIGTERM handler', () => {
    test.only('runs timeout', () => {
        jest.useFakeTimers();

        processEvents = {};

        process.on = jest.fn((signal, cb) => {
          processEvents[signal] = cb;
        });

        process.kill = jest.fn((pid, signal) => {
            processEvents[signal]();
        });

        require('./index.js');

        process.kill(process.pid, 'SIGTERM');

        jest.runAllTimers();

        expect(setTimeout.mock.calls.length).toBe(2);
    });
});

另一种更通用的方法是在 setTimeout 中模拟处理程序并测试已被调用的代码,如下所示:

index.js

var handlers = require('./handlers');

process.on('SIGTERM', () => {
    console.log('Got SIGTERM');
    setTimeout(handlers.someFunction, 300);
});

handlers.js

module.exports = {
    someFunction: () => {}
};

index.spec.js

describe('Test process SIGTERM handler', () => {
    test.only('sets someFunction as a SIGTERM handler', () => {
        jest.useFakeTimers();

        process.on = jest.fn((signal, cb) => {
            if (signal === 'SIGTERM') {
                cb();
            }
        });

        var handlerMock = jest.fn();

        jest.setMock('./handlers', {
            someFunction: handlerMock
        });

        require('./index');

        jest.runAllTimers();

        expect(handlerMock).toHaveBeenCalledTimes(1);
    });
});

【讨论】:

  • 谢谢!
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2015-03-05
  • 2021-09-15
  • 2019-08-23
  • 2020-03-30
  • 2021-09-25
  • 2021-06-16
  • 1970-01-01
相关资源
最近更新 更多