Zahra Ali
Zahra Ali

Reputation: 163

How to test a module using jest which imports an external library which is a constructor

I'm using a library, "pdfmake" and I want to write test cases using jest. I have a module pdf. Inside module pdf I'm exporting 2 functions. In both the exports, I'm using internal functions of "pdfmake" to generate pdfs.

Here is the code snippet: pdf.js

const PdfPrinter = require("pdfmake");
const fonts = require("./../shared/fonts");

const printer = new PdfPrinter(fonts);

const intiateDocCreation = docDefinition =>
  printer.createPdfKitDocument(docDefinition);

const finishDocCreation = (pdfDoc, pdfStream) => {
  pdfDoc.pipe(pdfStream);
  pdfDoc.end();
};
module.exports = {
  intiateDocCreation,
  finishDocCreation
};

I tried using

const PdfPrinter = require("pdfmake");
jest.mock("pdfmake", () => {
  return {
    createPdfKitDocument: jest.fn().mockImplementation(() => ({ a: "b" }))
  };
});

describe("test", () => {
  test("pdf", () => {
    const printer = new PdfPrinter(fonts);
    printer.createPdfKitDocument();
    expect(printer.createPdfKitDocument).toHaveBeenCalledTimes(1);
  });
});

Jest gives an error:

TypeError: PdfPrinter is not a constructor

Upvotes: 3

Views: 7402

Answers (1)

Lin Du
Lin Du

Reputation: 102617

You are almost there, if you want to mock the constructor of a node module(pdfmake), you need return a jest.fn() within the factory function of jest.mock.

E.g. pdf.js:

const PdfPrinter = require('pdfmake');
// const fonts = require('./../shared/fonts')
const fonts = {};

const printer = new PdfPrinter(fonts);

const intiateDocCreation = (docDefinition) => printer.createPdfKitDocument(docDefinition);

const finishDocCreation = (pdfDoc, pdfStream) => {
  pdfDoc.pipe(pdfStream);
  pdfDoc.end();
};

module.exports = {
  intiateDocCreation,
  finishDocCreation,
};

pdf.test.js:

const PdfPrinter = require('pdfmake');

jest.mock('pdfmake', () => {
  const mPdfMake = {
    createPdfKitDocument: jest.fn().mockImplementation(() => ({ a: 'b' })),
  };
  return jest.fn(() => mPdfMake);
});

describe('test', () => {
  test('pdf', () => {
    const fonts = {};
    const printer = new PdfPrinter(fonts);
    printer.createPdfKitDocument();
    expect(printer.createPdfKitDocument).toHaveBeenCalledTimes(1);
  });
});

Unit test result:

 PASS  src/stackoverflow/59250480/pdf.test.js (12.04s)
  test
    ✓ pdf (6ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.694s

Upvotes: 3

Related Questions