Home > Back-end >  How to mock a constructor instantiated class instance using jest?
How to mock a constructor instantiated class instance using jest?

Time:05-18

Given a class Person that instantiates & uses another class Logger, how can the Logger's method be verified to be called when Person is instantiated in the example below?

// Logger.ts
export default class Logger {
    constructor() {}
    log(m: String) {
        console.log(m);

        // Other operations that are outside testing (e.g., file write).
        throw Error('error');
    }
}

// Person.ts
import Logger from "./Logger";
export default class Person {
    constructor() {
        const logger = new Logger();
        logger.log('created');
    }
    // ...
}

// Person.test.ts
import Person from "./Person";
import Logger from "./Logger";
describe('Person', () => {
    it('calls Logger.log() on instantiation', () => {
        const mockLogger = new Logger();
        getCommitLinesMock = jest
            .spyOn(mockLogger, 'log')
            .mockImplementation(() => {});

        new Person(); // Should call Logger.log() on instantiation.

        expect(getCommitLinesMock).toBeCalled();
    });
});

One option is to pass Logger as a constructor argument like below:

class Person {
    constructor(logger: Logger) {
        logger.log('created');
    }
    // ...
}

However, is there any other way without changing the constructor to complete the test?

CodePudding user response:

You can mock the Logger class using jest.mock.

import Person from "./path/to/person";
import Logger from "./path/to/logger";

jest.mock("./path/to/logger");

describe("Person", () => {
  it("calls Logger.log() on instantiation", () => {
    new Person();
    expect(Logger).toHaveBeenCalled();
  });
});
  • Related