2017-09-29 76 views
7

我想單元測試在我的process.on('SIGTERM')回調中使用Jest的計時器,但它似乎永遠不會被調用。我正在使用jest.useFakeTimers(),雖然它似乎在某種程度上模擬了setTimeout調用,但它在檢查時並不會在setTimeout.mock對象中結束。NodeJS - Jest單元測試setTimeout在process.on回調

我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); 
    }); 
}); 

和測試失敗:

預期值是(使用===) :收到:和控制檯日誌輸出是:

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

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

如何獲得setTimeout在這裏跑?

+0

嘗試改變SIGTERM到SIGHUP了測試。 sigterm可能會殺死進程。還要嘗試刪除定時器1,並檢查控制檯日誌是否實際以同步方式工作。 – Jehy

回答

4

可以做些什麼,是嘲笑進程on方法,以確保您的處理程序將被調用kill方法。

確保處理程序將被調用的一種方法是模擬kill以及on

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); 
    }); 
});