Testing a node-cron Job function with Jest

Viewed 4685

I have a javascript class that contains a function that starts a cron job using the node-cron library. But I can't seem to find a way to test the class and the function.

The variables that control the node-cron are in a .env file. To do the testing I'm using jest. My job is started when the app.js of my node application is started(the class file is imported and is export instantiated)

.env file

#CRON JOB
FREQUENCY_CRON='30 00 * * *'
TIMEZONE="America/Sao_Paulo"
SCHEDULED=true
INACTIVE_EXPIRATION_TIME=2592000000 #30 DAYS

CronJob.js

class CronJob {
  constructor() {
    this.startJob();
  }

  async startJob() {
    cron.schedule(
      process.env.FREQUENCY_CRON,
      async () => {
        //DO SOME DATA PROCESSING 
      },
      {
        scheduled: process.env.SCHEDULED,
        timezone: process.env.TIMEZONE
      }
    );
  }
}

export default new CronJob();

1 Answers

You could use jest.mock(moduleName, factory, options) to mock node-cron module. Use dotenv package load the environment variables from .env before running the test cases.

E.g.

cronJob.js:

import cron from 'node-cron';

class CronJob {
  constructor() {
    this.startJob();
  }

  async startJob() {
    cron.schedule(
      process.env.FREQUENCY_CRON,
      async () => {
        console.log('DO SOME DATA PROCESSING');
      },
      {
        scheduled: process.env.SCHEDULED,
        timezone: process.env.TIMEZONE,
      },
    );
  }
}

export default new CronJob();

cronJob.test.js:

import cron from 'node-cron';
import path from 'path';

require('dotenv').config({ path: path.resolve(__dirname, './.env') });

jest.mock('node-cron', () => {
  return {
    schedule: jest.fn(),
  };
});

describe('61765291', () => {
  it('should pass', () => {
    const logSpy = jest.spyOn(console, 'log');
    cron.schedule.mockImplementationOnce(async (frequency, callback) => await callback());
    require('./cronJob');
    expect(logSpy).toBeCalledWith('DO SOME DATA PROCESSING');
    expect(cron.schedule).toBeCalledWith('30 00 * * *', expect.any(Function), {
      scheduled: 'true',
      timezone: 'America/Sao_Paulo',
    });
  });
});

.env:

#CRON JOB
FREQUENCY_CRON='30 00 * * *'
TIMEZONE="America/Sao_Paulo"
SCHEDULED=true
INACTIVE_EXPIRATION_TIME=2592000000 #30 DAYS

unit test results with 100% coverage:

 PASS  stackoverflow/61765291/cronJob.test.js (8.148s)
  61765291
    ✓ should pass (30ms)

  console.log
    DO SOME DATA PROCESSING

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 cronJob.js |     100 |      100 |     100 |     100 |                   
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.145s, estimated 10s
Related