Challenge 2: Mock an Interface Dependency — Possible Solution ==================================================================== // order-service.ts interface Order { id: string; email: string; } interface Database { save(order: Order): void; } interface Mailer { send(to: string): void; } class OrderService { constructor( private db: Database, private mailer: Mailer ) {} placeOrder(order: Order): void { this.db.save(order); this.mailer.send(order.email); } } export { OrderService, Database, Mailer, Order }; // order-service.test.ts import { OrderService, Database, Mailer, Order } from "./order-service"; describe("OrderService", () => { it("saves the order to the database", () => { const db: Database = { save: jest.fn() }; const mailer: Mailer = { send: jest.fn() }; const order: Order = { id: "1", email: "customer@example.com" }; const service = new OrderService(db, mailer); service.placeOrder(order); expect(db.save).toHaveBeenCalledTimes(1); expect(db.save).toHaveBeenCalledWith(order); }); it("emails the customer after saving", () => { const db: Database = { save: jest.fn() }; const mailer: Mailer = { send: jest.fn() }; const order: Order = { id: "2", email: "someone@example.com" }; const service = new OrderService(db, mailer); service.placeOrder(order); expect(mailer.send).toHaveBeenCalledWith("someone@example.com"); }); it("does not email if saving throws", () => { const db: Database = { save: jest.fn(() => { throw new Error("db down"); }) }; const mailer: Mailer = { send: jest.fn() }; const order: Order = { id: "3", email: "x@example.com" }; const service = new OrderService(db, mailer); expect(() => service.placeOrder(order)).toThrow("db down"); expect(mailer.send).not.toHaveBeenCalled(); }); }); WHY THIS WORKS -------------- - Because OrderService depends on the Database and Mailer interfaces (not concrete classes), a mock only needs to be a plain object whose shape matches the interface — TypeScript's structural typing accepts it directly. - jest.fn() gives each mock method call-tracking (toHaveBeenCalledTimes, toHaveBeenCalledWith) without needing any mocking library beyond Jest itself. - The third test demonstrates a genuinely useful assertion mocks make easy: proving that a failure in one dependency (the database) prevents an unwanted side effect in another (sending an email).