← Back to TypeScript Course | Chapter 24: Testing TypeScript | Lesson 4 of 6

Mocking with Types

Mocks replace real dependencies with controlled test implementations. TypeScript can describe mock objects and functions so tests remain aligned with the production API.

Mocking a Function

Mocking a single function with jest.fn<ReturnType, Args>() preserves the original function's call signature, so calling the mock with wrong argument types is flagged by the type checker just like calling the real function would be.

Example: Mocking a Function

typescript
type Add = (a: number, b: number) => number;
const mockAdd: Add = (a, b) => a + b;
console.log(mockAdd(2, 3));

Mocking Object Dependencies

Mocking an object dependency (like a service class) means providing a fake object that satisfies the same interface, so TypeScript verifies the mock actually implements every method the real dependency exposes.

Example: Mocking Object Dependencies

typescript
interface Logger {
  log(msg: string): void;
}
const mockLogger: Logger = { log: (msg) => console.log("MOCK:", msg) };
mockLogger.log("test message");

Recording Calls

Recording calls on a typed mock — via mock.calls — preserves the argument types you passed, so asserting expect(mockFn.mock.calls[0][0]).toBe(...) stays type-safe rather than resolving to any.

Example: Recording Calls

typescript
const calls: [string][] = [];
function mockLog(msg: string) {
  calls.push([msg]);
}
mockLog("hello");
console.log(calls[0][0]);

Partial Mocks

A partial mock only replaces the methods relevant to the test while leaving the rest of a real object intact, typed with Partial<T> so the compiler tracks which parts are genuinely mocked versus real.

Example: Partial Mocks

typescript
interface Config {
  apiUrl: string;
  timeout: number;
}
const partialMock: Partial<Config> = { apiUrl: "http://test" };
console.log(partialMock);

Mocking Async Dependencies

Mocking an async dependency means the mock function must return a Promise matching the real method's resolved type, so mockResolvedValue(...) gets type-checked against the actual async signature.

Example: Mocking Async Dependencies

typescript
interface Api {
  fetchUser(): Promise<string>;
}
const mockApi: Api = { fetchUser: () => Promise.resolve("mocked-user") };
mockApi.fetchUser().then(console.log);
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.