← 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.
Syntax
typescript
const mockFn = jest.fn<returnType, [paramType]>();
mockFn.mockReturnValue(value);
jest.mock("./module");

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);
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Typing a mock as any, so the test no longer checks that the mock matches the real interface.
  2. Forgetting to reset or clear mocks between tests, so call counts leak from one test to another.
  3. Mocking only part of an object and casting it with as Service, which hides missing methods.
🔒

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.