Dada una clase Person que crea instancias y usa otra clase Logger , ¿cómo se puede verificar que se llame al método Logger cuando se crea una instancia de Person en el siguiente ejemplo?
// Logger.ts export default class Logger { constructor() {} log(m: String) { console.log(m); // Other operations that are outside testing (eg, 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(); }); }); Una opción es pasar Logger como un argumento constructor como se muestra a continuación:
class Person { constructor(logger: Logger) { logger.log('created'); } // ... }Sin embargo, ¿hay alguna otra forma sin cambiar el constructor para completar la prueba?
Puede usar jest.mock(moduleName, factory, options) y se burlará automáticamente de todas las exportaciones del módulo dado.
Entonces puede hacer jest.mock("./Logger") y el constructor Logger y todos sus métodos serán reemplazados con funciones simuladas ( que devuelven undefined por defecto ) y ahora puede espiar el comportamiento del constructor y todo sus métodos.
import Person from "./Person"; import Logger from "./Logger"; jest.mock("./Logger"); describe("Person", () => { it("calls the Logger constructor on instantiation", () => { new Person(); expect(Logger).toHaveBeenCalledTimes(1); }); }); Todas las funciones simuladas tienen una propiedad .mock especial donde varios datos relacionados con la función simulada están disponibles, incluidas las instancias que ha creado la función constructora simulada, cuando se invocó con new .
Por lo tanto, todas las instancias creadas por el Logger.mock.instances Logger puede usar esto para espiar las llamadas al método.
import Person from "./Person"; import Logger from "./Logger"; jest.mock("./Logger"); describe("Person", () => { it("calls the Logger constructor and the log method on instantiation", () => { new Person(); expect(Logger).toHaveBeenCalledTimes(1); const mockLoggerInstance = Logger.mock.instances[0]; const mockLogMethod = mockLoggerInstance.log; expect(mockLogMethod).toHaveBeenCalledTimes(1); }); });