Search code examples
javascriptnode.jsunit-testingmocha.jssinon

How to unit test node-cron job


I need to call a function using node-cron and want to write a unit test case for that. the unit test case should be able to test if the function is getting calling based on the pattern.

Below is my code

const server = (module.exports = {
  cronJob: null,
  scheduledJob: function(pattern) {
    server.cronJob = cron.schedule(pattern, () => {
      server.run();
    });
  },
  run: function() {
    console.log("run called");
  },
}); 
describe("entry point test suite", () => {
  it("should call function every second", (done) => {
    const pattern = "* * * * * *";
    let spy = sinon.spy(server, "run");
    server.scheduledJob(pattern);
    server.cronJob.Start();
    // to do wait for 3 sencond
    server.cronJob.Stop();
    expect(spy.callCount).eq(3);
  });
}); 

Two questions:

  1. other than setTimeout what option I have to wait for 3 seconds so that cron job will run 3 times as pattern is for each second.

  2. This test is failing with error server.cronjob.start is not a function.

How can I make this work?


Solution

  • Here is the unit testing solution:

    server.js:

    const cron = require("node-cron");
    
    const server = (module.exports = {
      cronJob: null,
      scheduledJob: function(pattern) {
        server.cronJob = cron.schedule(pattern, () => {
          server.run();
        });
      },
      run: function() {
        console.log("run called");
      },
    });
    

    server.test.js:

    const server = require("./server");
    const sinon = require("sinon");
    const cron = require("node-cron");
    const { expect } = require("chai");
    
    describe("57208090", () => {
      afterEach(() => {
        sinon.restore();
      });
      describe("#scheduledJob", () => {
        it("should schedule job", () => {
          const pattern = "* * * * * *";
          const runStub = sinon.stub(server, "run");
          const scheduleStub = sinon
            .stub(cron, "schedule")
            .yields()
            .returns({});
          server.scheduledJob(pattern);
          sinon.assert.calledWith(scheduleStub, pattern, sinon.match.func);
          sinon.assert.calledOnce(runStub);
          expect(server.cronJob).to.be.eql({});
        });
      });
    
      describe("#run", () => {
        it("should run server", () => {
          const logSpy = sinon.spy(console, "log");
          server.run();
          sinon.assert.calledWith(logSpy, "run called");
        });
      });
    });
    

    Unit test result with 100% coverage:

      57208090
        #scheduledJob
          ✓ should schedule job
        #run
    run called
          ✓ should run server
    
    
      2 passing (12ms)
    
    ----------------|----------|----------|----------|----------|-------------------|
    File            |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ----------------|----------|----------|----------|----------|-------------------|
    All files       |      100 |      100 |      100 |      100 |                   |
     server.js      |      100 |      100 |      100 |      100 |                   |
     server.test.js |      100 |      100 |      100 |      100 |                   |
    ----------------|----------|----------|----------|----------|-------------------|
    

    You asked for unit testing. If you need an integration testing, please create a new post.

    Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/57208090