### Install jest-mock-extended Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Install the library as a development dependency using npm or yarn. ```bash npm install jest-mock-extended --save-dev ``` ```bash yarn add jest-mock-extended --dev ``` -------------------------------- ### stub() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Creates a lightweight no-op stub that returns a fresh `jest.fn()` for any accessed property, without `calledWith` support or tracking setup. ```APIDOC ## stub() ### Description Creates a bare-minimum stub that returns a fresh `jest.fn()` for any accessed property, with no `calledWith` support or tracking setup. Use when you need a structural stand-in without assertion capabilities. ### Usage ```typescript import { stub } from 'jest-mock-extended'; interface Logger { log(msg: string): void; } const logger = stub(); // Each access returns a jest.fn() logger.log('hello'); expect(logger.log).toHaveBeenCalledWith('hello'); ``` ### Example for Dependency Injection ```typescript class App { constructor(private logger: Logger) {} run() { this.logger.log('App started'); } } const app = new App(stub()); app.run(); // logger calls are silently swallowed ``` ``` -------------------------------- ### mock() — Create a typed shallow mock Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Creates a `MockProxy` that wraps every property access in a `jest.fn()` with the `calledWith()` extension attached. An optional partial implementation object pre-fills specific properties or methods. The optional `opts.fallbackMockImplementation` is invoked for any call that has no matching `calledWith` setup. ```APIDOC ## mock(mockImplementation?, opts?) ### Description Creates a `MockProxy` that wraps every property access in a `jest.fn()` with the `calledWith()` extension attached. An optional partial implementation object pre-fills specific properties or methods. The optional `opts.fallbackMockImplementation` is invoked for any call that has no matching `calledWith` setup. ### Parameters #### Mock Implementation (Optional) - `mockImplementation` (object) - An object with pre-filled properties or methods. #### Options (Optional) - `opts.fallbackMockImplementation` (function) - A function invoked for any call that has no matching `calledWith` setup. ### Request Example ```typescript import { mock, MockProxy } from 'jest-mock-extended'; interface UserService { getUser(id: number): { id: number; name: string }; deleteUser(id: number): boolean; updateUser(id: number, name: string): void; } // Basic mock — all methods are jest.fn() by default const userService = mock(); userService.getUser.mockReturnValue({ id: 1, name: 'Alice' }); expect(userService.getUser(1)).toEqual({ id: 1, name: 'Alice' }); expect(userService.getUser).toHaveBeenCalledWith(1); // Pre-filled partial implementation const userServiceWithImpl = mock({ getUser: (id) => ({ id, name: 'Bob' }), deleteUser: () => true, }); expect(userServiceWithImpl.getUser(42)).toEqual({ id: 42, name: 'Bob' }); // Fallback throws for unmocked calls (useful for strict testing) const strictService = mock( {}, { fallbackMockImplementation: () => { throw new Error('Method not mocked'); }, } ); expect(() => strictService.getUser(1)).toThrowError('Method not mocked'); // Typed variable assignment let svc: MockProxy; svc = mock(); svc.deleteUser.mockReturnValue(false); expect(svc.deleteUser(99)).toBe(false); ``` ``` -------------------------------- ### Build Reusable Matchers with `Matcher` and `MatcherCreator` Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Create reusable, named matchers using `Matcher` or the `MatcherCreator` factory. These custom matchers can be used with `calledWith()` and `toHaveBeenCalledWith()`. The example shows creating a range checker and a length checker. ```typescript import { Matcher, MatcherCreator } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended'; // Simple reusable matcher: checks if a number is within a range export const inRange: MatcherCreator = ({ min, max } = { min: 0, max: 100 }) => new Matcher( (actualValue: number) => actualValue >= min && actualValue <= max, `inRange(${min}, ${max})` ); // Matcher with different expected vs actual types export const hasLength: MatcherCreator = (expectedLength) => new Matcher( (actual) => actual.length === expectedLength, `hasLength(${expectedLength})` ); interface Validator { check(score: number, tags: string[]): boolean; } const validator = mock(); validator.check .calledWith(inRange({ min: 0, max: 100 }), hasLength(3)) .mockReturnValue(true); expect(validator.check(50, ['a', 'b', 'c'])).toBe(true); expect(validator.check(150, ['a', 'b', 'c'])).toBeUndefined(); // out of range expect(validator.check(50, ['a', 'b'])).toBeUndefined(); // wrong length ``` ```typescript import { Matcher, MatcherCreator } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended'; // Simple reusable matcher: checks if a number is within a range export const inRange: MatcherCreator = ({ min, max } = { min: 0, max: 100 }) => new Matcher( (actualValue: number) => actualValue >= min && actualValue <= max, `inRange(${min}, ${max})` ); // Matcher with different expected vs actual types export const hasLength: MatcherCreator = (expectedLength) => new Matcher( (actual) => actual.length === expectedLength, `hasLength(${expectedLength})` ); interface Validator { check(score: number, tags: string[]): boolean; } const validator = mock(); validator.check .calledWith(inRange({ min: 0, max: 100 }), hasLength(3)) .mockReturnValue(true); // Use in toHaveBeenCalledWith validator.check(75, ['x', 'y', 'z']); expect(validator.check).toHaveBeenCalledWith(inRange({ min: 0, max: 100 }), hasLength(3)); ``` -------------------------------- ### Create Lightweight Stubs with stub() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `stub()` to create a minimal mock object that returns a fresh `jest.fn()` for any accessed property. This is ideal for dependency injection when assertions on the mock are not required, as calls are silently ignored. ```typescript import { stub } from 'jest-mock-extended'; interface Logger { log(msg: string): void; warn(msg: string): void; error(msg: string, code: number): void; } const logger = stub(); // Each access returns a jest.fn() logger.log('hello'); logger.warn('careful'); expect(logger.log).toHaveBeenCalledWith('hello'); expect(logger.warn).toHaveBeenCalledWith('careful'); // Useful for dependency injection where you don't need assertions class App { constructor(private logger: Logger) {} run() { this.logger.log('App started'); } } const app = new App(stub()); app.run(); // no assertion needed — logger calls are silently swallowed ``` -------------------------------- ### matches(fn) Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Creates a one-off `Matcher` from any predicate function. Useful when no built-in matcher covers the assertion logic needed. ```APIDOC ## `matches(fn)` — Custom inline matcher Creates a one-off `Matcher` from any predicate function. Useful when no built-in matcher covers the assertion logic needed. ```typescript import { matches } from 'jest-mock-extended'; import { jest } from '@jest/globals'; interface ReportService { generate(title: string, data: number[]): string; } const fn = jest.fn(); fn('Q1 Report', [100, 200, 300]); fn('Q2 Report', [400, 500]); // Custom predicate: title must start with 'Q' expect(fn).toHaveBeenCalledWith( matches((title: string) => title.startsWith('Q')), anyArray() // combined with built-in matchers ); // Negative assertion expect(fn).not.toHaveBeenCalledWith( matches((title: string) => title.startsWith('Annual')), expect.anything() ); // In calledWith setup import { mock } from 'jest-mock-extended'; import { anyArray } from 'jest-mock-extended'; const svc = mock(); svc.generate .calledWith(matches((t) => t.length > 5), anyArray()) .mockReturnValue('Long title report'); expect(svc.generate('Q1 Summary', [1, 2])).toBe('Long title report'); expect(svc.generate('Q1', [1, 2])).toBeUndefined(); // title too short, no match ``` ``` -------------------------------- ### Matcher and MatcherCreator Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Build reusable, named matchers by instantiating `Matcher` directly or via the `MatcherCreator` factory pattern. Custom matchers work in both `calledWith()` and `toHaveBeenCalledWith()`. ```APIDOC ## `Matcher` and `MatcherCreator` — Custom reusable matchers Build reusable, named matchers by instantiating `Matcher` directly or via the `MatcherCreator` factory pattern. Custom matchers work in both `calledWith()` and `toHaveBeenCalledWith()`. ```typescript import { Matcher, MatcherCreator } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended'; // Simple reusable matcher: checks if a number is within a range export const inRange: MatcherCreator = ({ min, max } = { min: 0, max: 100 }) => new Matcher( (actualValue: number) => actualValue >= min && actualValue <= max, `inRange(${min}, ${max})` ); // Matcher with different expected vs actual types export const hasLength: MatcherCreator = (expectedLength) => new Matcher( (actual) => actual.length === expectedLength, `hasLength(${expectedLength})` ); interface Validator { check(score: number, tags: string[]): boolean; } const validator = mock(); validator.check .calledWith(inRange({ min: 0, max: 100 }), hasLength(3)) .mockReturnValue(true); expect(validator.check(50, ['a', 'b', 'c'])).toBe(true); expect(validator.check(150, ['a', 'b', 'c'])).toBeUndefined(); // out of range expect(validator.check(50, ['a', 'b'])).toBeUndefined(); // wrong length // Use in toHaveBeenCalledWith validator.check(75, ['x', 'y', 'z']); expect(validator.check).toHaveBeenCalledWith(inRange({ min: 0, max: 100 }), hasLength(3)); ``` ``` -------------------------------- ### Mock an Interface with jest-mock-extended Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Demonstrates how to mock an entire interface using the mock() function. Ensure all methods are explicitly mocked if they are expected to be called. ```typescript import { mock } from 'jest-mock-extended'; interface PartyProvider { getPartyType: () => string; getSongs: (type: string) => string[]; start: (type: string) => void; } describe('Party Tests', () => { test('Mock out an interface', () => { const mock = mock(); mock.start('disco party'); expect(mock.start).toHaveBeenCalledWith('disco party'); }); test('mock out a return type', () => { const mock = mock(); mock.getPartyType.mockReturnValue('west coast party'); expect(mock.getPartyType()).toBe('west coast party'); }); test('throwing an error if we forget to specify the return value') const mock = mock( {}, { fallbackMockImplementation: () => { throw new Error('not mocked'); }, } ); expect(() => mock.getPartyType()).toThrowError('not mocked'); }); }); ``` -------------------------------- ### .calledWith(...args) Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Configure mock return values based on specific arguments passed to a mock function. This allows for fine-grained control over mock behavior for different call signatures. ```APIDOC ## .calledWith(...args) ### Description Every method on a `MockProxy` or `DeepMockProxy` has a `.calledWith()` extension that returns a scoped `jest.fn()`. Configure `.mockReturnValue()`, `.mockResolvedValue()`, `.mockImplementation()`, etc. on that scoped fn. Multiple `calledWith` registrations are evaluated in reverse registration order (last-registered wins for identical args). ### Method Mock function extension ### Endpoint N/A (TypeScript/JavaScript API) ### Parameters - **...args** (any): The arguments to match for this specific mock configuration. ### Request Example ```typescript import { mock } from 'jest-mock-extended'; import { anyNumber, anyString } from 'jest-mock-extended'; interface Calculator { add(a: number, b: number): number; format(value: number, label: string): string; } const calc = mock(); // Literal argument matching calc.add.calledWith(1, 2).mockReturnValue(3); calc.add.calledWith(10, 20).mockReturnValue(30); // Matcher-based argument matching calc.add.calledWith(anyNumber(), anyNumber()).mockReturnValue(99); // Mixed literals and matchers calc.format.calledWith(42, anyString()).mockReturnValue('42 items'); // Override previous registration with same args (last-registered wins) calc.add.calledWith(1, 2).mockReturnValue(100); // Async calledWith interface ApiClient { fetchData(id: string): Promise<{ value: number }>; } const client = mock(); client.fetchData.calledWith('abc').mockResolvedValue({ value: 42 }); // Used with jest.expect matchers too calc.add.calledWith(expect.any(Number), expect.any(Number)).mockReturnValue(0); ``` ### Response #### Success Response (N/A - configures mock behavior) Configures the mock function's behavior for specific argument combinations. #### Response Example N/A ``` -------------------------------- ### Basic Deep Mocking with jest-mock-extended Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Use mockDeep for mocking nested properties and method return values. Ensure Test1 and DeepMockProxy are defined in your environment. ```typescript import { mockDeep } from 'jest-mock-extended'; const mockObj: DeepMockProxy = mockDeep(); mockObj.deepProp.getNumber.calledWith(1).mockReturnValue(4); expect(mockObj.deepProp.getNumber(1)).toBe(4); ``` -------------------------------- ### mockReset(mock) Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Resets the call history and mock implementations of a mock proxy. After a reset, all methods return `undefined` until reconfigured. ```APIDOC ## mockReset(mock) ### Description Resets every `jest.fn()` within the mock proxy to its initial unconfigured state — removing `calledWith` bindings, return values, and call history. After a reset, all methods return `undefined`. ### Usage ```typescript import { mock, mockReset } from 'jest-mock-extended'; interface PaymentService { charge(amount: number): boolean; } const payments = mock(); // ... configure and use payments ... mockReset(payments); // Now payments.charge(100) will return undefined ``` ### Example with `beforeEach` ```typescript describe('PaymentService tests', () => { const svc = mock(); beforeEach(() => mockReset(svc)); test('charge returns true for valid amount', () => { svc.charge.mockReturnValue(true); expect(svc.charge(99)).toBe(true); }); test('no leakage from previous test', () => { // This test will not see the configuration from the previous test expect(svc.charge(99)).toBeUndefined(); }); }); ``` ``` -------------------------------- ### Create Jest Mock Functions with calledWith() Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Use mockFn() to create a Jest mock function that includes the calledWith() extension for advanced argument matching. ```typescript type MyFn = (x: number, y: number) => Promise; const fn = mockFn(); fn.calledWith(1, 2).mockReturnValue('str'); ``` -------------------------------- ### Create standalone typed mocks with `mockFn()` Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `mockFn()` to create a standalone, type-safe `jest.fn()` that includes the `.calledWith()` extension. This is useful for mocking function dependencies passed as arguments. ```typescript import { mockFn } from 'jest-mock-extended'; import { anyNumber } from 'jest-mock-extended'; type TransformFn = (input: number, multiplier: number) => Promise; const transform = mockFn(); // Standard jest.fn() API works transform.mockResolvedValue('default'); expect(await transform(1, 1)).toBe('default'); // calledWith scoping transform.calledWith(5, 2).mockResolvedValue('ten'); transform.calledWith(anyNumber(), 0).mockResolvedValue('zero'); expect(await transform(5, 2)).toBe('ten'); expect(await transform(99, 0)).toBe('zero'); // Type safety: TypeScript enforces correct argument types // transform.calledWith('bad', 2) // TS error: Argument of type 'string' is not assignable to 'number' // Inspect calls transform(3, 4); expect(transform).toHaveBeenCalledTimes(3); expect(transform.mock.calls[2]).toEqual([3, 4]); ``` -------------------------------- ### mockDeep() — Create a typed deep mock Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Returns a `DeepMockProxy` that recursively proxies nested object properties, enabling `calledWith()` chaining at any depth. Pass `{ funcPropSupport: true }` to also support mocking properties on function-typed class members. ```APIDOC ## mockDeep(opts?, mockImplementation?) ### Description Returns a `DeepMockProxy` that recursively proxies nested object properties, enabling `calledWith()` chaining at any depth. Pass `{ funcPropSupport: true }` to also support mocking properties on function-typed class members. ### Parameters #### Options (Optional) - `opts` (object) - Configuration options. `funcPropSupport: true` enables mocking properties on function-typed class members. #### Mock Implementation (Optional) - `mockImplementation` (object) - An object with pre-filled properties or methods for deep mocking. ### Request Example ```typescript import { mockDeep, DeepMockProxy } from 'jest-mock-extended'; class Database { connection: { query(sql: string): string[]; transaction: { begin(): void; commit(): void; }; }; } // Deep mock — nested properties are automatically proxied const db = mockDeep(); db.connection.query.calledWith('SELECT * FROM users').mockReturnValue(['alice', 'bob']); expect(db.connection.query('SELECT * FROM users')).toEqual(['alice', 'bob']); // Three-level deep mock db.connection.transaction.begin.mockImplementation(() => { /* no-op */ }); db.connection.transaction.commit(); expect(db.connection.transaction.commit).toHaveBeenCalledTimes(1); // With fallback for strict deep mocking const strictDb = mockDeep({ fallbackMockImplementation: () => { throw new Error('not mocked'); }, }); expect(() => strictDb.connection.query('DROP TABLE')).toThrowError('not mocked'); // funcPropSupport: true — mock both invocation and properties of function-valued class members interface FnWithProps { (x: number): number; metadata: { version: string }; helper: { compute(n: number): number }; } class Service { fn: FnWithProps; } const svc = mockDeep({ funcPropSupport: true }); svc.fn.calledWith(5).mockReturnValue(10); svc.fn.helper.compute.calledWith(3).mockReturnValue(9); expect(svc.fn(5)).toBe(10); expect(svc.fn.helper.compute(3)).toBe(9); // Deep mock with partial implementation const dbWithImpl = mockDeep({ connection: { query: () => ['hardcoded'] }, }); expect(dbWithImpl.connection.query('anything')).toEqual(['hardcoded']); dbWithImpl.connection.transaction.begin(); // still a jest.fn() expect(dbWithImpl.connection.transaction.begin).toHaveBeenCalled(); ``` ``` -------------------------------- ### Create Typed Shallow Mock with mock() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `mock()` to create a shallow mock proxy for a TypeScript interface or class. All properties and methods are automatically converted to `jest.fn()`. You can provide a partial implementation or a fallback for unmocked calls. ```typescript import { mock, MockProxy } from 'jest-mock-extended'; interface UserService { getUser(id: number): { id: number; name: string }; deleteUser(id: number): boolean; updateUser(id: number, name: string): void; } // Basic mock — all methods are jest.fn() by default const userService = mock(); userService.getUser.mockReturnValue({ id: 1, name: 'Alice' }); expect(userService.getUser(1)).toEqual({ id: 1, name: 'Alice' }); expect(userService.getUser).toHaveBeenCalledWith(1); ``` ```typescript // Pre-filled partial implementation const userServiceWithImpl = mock({ getUser: (id) => ({ id, name: 'Bob' }), deleteUser: () => true, }); expect(userServiceWithImpl.getUser(42)).toEqual({ id: 42, name: 'Bob' }); ``` ```typescript // Fallback throws for unmocked calls (useful for strict testing) const strictService = mock( {}, { fallbackMockImplementation: () => { throw new Error('Method not mocked'); }, } ); expect(() => strictService.getUser(1)).toThrowError('Method not mocked'); ``` ```typescript // Typed variable assignment let svc: MockProxy; svc = mock(); svc.deleteUser.mockReturnValue(false); expect(svc.deleteUser(99)).toBe(false); ``` -------------------------------- ### Deep Mocking with Function Property Support Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Enable function property support in mockDeep by passing an option. This allows mocking properties on functions returned by methods. ```typescript import { mockDeep } from 'jest-mock-extended'; const mockObj: DeepMockProxy = mockDeep({ funcPropSupport: true }); mockObj.deepProp.calledWith(1).mockReturnValue(3) mockObj.deepProp.getNumber.calledWith(1).mockReturnValue(4); expect(mockObj.deepProp(1)).toBe(3); expect(mockObj.deepProp.getNumber(1)).toBe(4); ``` -------------------------------- ### Create Typed Deep Mock with mockDeep() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `mockDeep()` to create a deep mock proxy that recursively mocks nested properties. This is useful for complex object hierarchies. The `funcPropSupport` option allows mocking properties on function-typed class members. ```typescript import { mockDeep, DeepMockProxy } from 'jest-mock-extended'; class Database { connection: { query(sql: string): string[]; transaction: { begin(): void; commit(): void; }; }; } // Deep mock — nested properties are automatically proxied const db = mockDeep(); db.connection.query.calledWith('SELECT * FROM users').mockReturnValue(['alice', 'bob']); expect(db.connection.query('SELECT * FROM users')).toEqual(['alice', 'bob']); ``` ```typescript // Three-level deep mock db.connection.transaction.begin.mockImplementation(() => { /* no-op */ }); db.connection.transaction.commit(); expect(db.connection.transaction.commit).toHaveBeenCalledTimes(1); ``` ```typescript // With fallback for strict deep mocking const strictDb = mockDeep({ fallbackMockImplementation: () => { throw new Error('not mocked'); }, }); expect(() => strictDb.connection.query('DROP TABLE')).toThrowError('not mocked'); ``` ```typescript // funcPropSupport: true — mock both invocation and properties of function-valued class members interface FnWithProps { (x: number): number; metadata: { version: string }; helper: { compute(n: number): number }; } class Service { fn: FnWithProps; } const svc = mockDeep({ funcPropSupport: true }); svc.fn.calledWith(5).mockReturnValue(10); svc.fn.helper.compute.calledWith(3).mockReturnValue(9); expect(svc.fn(5)).toBe(10); expect(svc.fn.helper.compute(3)).toBe(9); ``` ```typescript // Deep mock with partial implementation const dbWithImpl = mockDeep({ connection: { query: () => ['hardcoded'] }, }); expect(dbWithImpl.connection.query('anything')).toEqual(['hardcoded']); dbWithImpl.connection.transaction.begin(); // still a jest.fn() expect(dbWithImpl.connection.transaction.begin).toHaveBeenCalled(); ``` -------------------------------- ### mockFn() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Creates a standalone typed jest.fn() with the calledWith() extension, useful for mocking function-type dependencies passed as arguments. ```APIDOC ## mockFn() ### Description Creates a standalone typed `jest.fn()` with the `calledWith()` extension, without needing to wrap an interface. Useful for mocking function-type dependencies passed as arguments. ### Method Function mock creation ### Endpoint N/A (TypeScript/JavaScript API) ### Parameters - **T** (type): The type of the function to mock. ### Request Example ```typescript import { mockFn } from 'jest-mock-extended'; import { anyNumber } from 'jest-mock-extended'; type TransformFn = (input: number, multiplier: number) => Promise; const transform = mockFn(); // Standard jest.fn() API works transform.mockResolvedValue('default'); // calledWith scoping transform.calledWith(5, 2).mockResolvedValue('ten'); transform.calledWith(anyNumber(), 0).mockResolvedValue('zero'); // Type safety: TypeScript enforces correct argument types // transform.calledWith('bad', 2) // TS error: Argument of type 'string' is not assignable to 'number' // Inspect calls transform(3, 4); ``` ### Response #### Success Response (N/A - returns a mock function) A typed `jest.fn()` with `calledWith` capabilities. #### Response Example N/A ``` -------------------------------- ### Built-in Matchers Source: https://context7.com/marchaos/jest-mock-extended/llms.txt A suite of pre-built `Matcher` instances compatible with `calledWith()` and `toHaveBeenCalledWith()`, implementing Jest's asymmetric matcher interface for type-safe argument matching. ```APIDOC ## Built-in Matchers ### Description A suite of pre-built `Matcher` instances compatible with both `calledWith()` and `toHaveBeenCalledWith()`. All matchers implement Jest's asymmetric matcher interface. ### Available Matchers - `any` - `anyBoolean`, `anyNumber`, `anyString`, `anyFunction`, `anySymbol`, `anyObject`, `anyArray`, `anyMap`, `anySet` - `isA(Constructor)` - `arrayIncludes(value)` - `setHas(value)` - `mapHas(key)` - `objectContainsKey(key)` - `objectContainsValue(value)` - `notNull` - `notUndefined` - `notEmpty` ### Usage with `calledWith` ```typescript import { mock, anyArray, anyObject, anyString, anyBoolean, anyNumber, anyFunction, isA, arrayIncludes, setHas, mapHas, objectContainsKey, objectContainsValue, notNull, notUndefined, notEmpty } from 'jest-mock-extended'; interface DataProcessor { process(items: any[], config: object, label: string): string; validate(value: any): boolean; store(map: Map, set: Set): void; } const dp = mock(); // Example: anyArray, anyObject, anyString dp.process.calledWith(anyArray(), anyObject(), anyString()).mockReturnValue('ok'); expect(dp.process([1, 2], { strict: true }, 'run')).toBe('ok'); // Example: anyBoolean, anyNumber, anyFunction dp.validate.calledWith(anyBoolean()).mockReturnValue(true); dp.validate.calledWith(anyNumber()).mockReturnValue(true); dp.validate.calledWith(anyFunction()).mockReturnValue(false); expect(dp.validate(true)).toBe(true); expect(dp.validate(42)).toBe(true); expect(dp.validate(() => {})).toBe(false); // Example: isA class Config {} dp.validate.calledWith(isA(Config)).mockReturnValue(true); expect(dp.validate(new Config())).toBe(true); expect(dp.validate({})).toBe(false); // Example: arrayIncludes, setHas, mapHas, objectContainsKey, objectContainsValue dp.validate.calledWith(arrayIncludes('admin')).mockReturnValue(true); expect(dp.validate(['admin', 'user'])).toBe(true); dp.store.calledWith(mapHas('userId'), setHas('active')).mockReturnValue(undefined); dp.store(new Map([['userId', 1]]), new Set(['active'])); expect(dp.store).toHaveBeenCalledWith(mapHas('userId'), setHas('active')); // Example: notNull, notUndefined, notEmpty const fn = mock<{ run(x: any): void }>(); fn.run.calledWith(notNull()).mockReturnValue(undefined); fn.run.calledWith(notEmpty()).mockReturnValue(undefined); ``` ### Usage with `toHaveBeenCalledWith` ```typescript const mockFn2 = mock<{ send(data: string[], count: number): void }>(); mockFn2.send(['a', 'b'], 2); // Using matchers with toHaveBeenCalledWith expect(mockFn2.send).toHaveBeenCalledWith(anyArray(), anyNumber()); expect(mockFn2.send).toHaveBeenCalledWith(arrayIncludes('a'), 2); expect(mockFn2.send).not.toHaveBeenCalledWith(anyArray(), 99); ``` ``` -------------------------------- ### Creating a Custom Matcher with MatcherCreator Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Define custom matchers using MatcherCreator. The expectedValue is optional and can be typed independently of the actualValue using generics. ```typescript import { MatcherCreator, Matcher } from 'jest-mock-extended'; // expectedValue is optional export const myMatcher: MatcherCreator = (expectedValue) => new Matcher((actualValue) => { return (expectedValue === actualValue && actualValue.isSpecial); }); ``` -------------------------------- ### Configure argument-scoped mock return values with `.calledWith()` Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `.calledWith()` to define mock return values for specific argument combinations. Multiple registrations for the same arguments are resolved in reverse order of definition. Supports literal values, matchers like `anyNumber()`, and `expect.any()`. ```typescript import { mock } from 'jest-mock-extended'; import { anyNumber, anyString } from 'jest-mock-extended'; interface Calculator { add(a: number, b: number): number; format(value: number, label: string): string; } const calc = mock(); // Literal argument matching calc.add.calledWith(1, 2).mockReturnValue(3); calc.add.calledWith(10, 20).mockReturnValue(30); expect(calc.add(1, 2)).toBe(3); expect(calc.add(10, 20)).toBe(30); expect(calc.add(5, 5)).toBeUndefined(); // no match → undefined // Matcher-based argument matching calc.add.calledWith(anyNumber(), anyNumber()).mockReturnValue(99); expect(calc.add(7, 8)).toBe(99); // Mixed literals and matchers calc.format.calledWith(42, anyString()).mockReturnValue('42 items'); expect(calc.format(42, 'items')).toBe('42 items'); expect(calc.format(42, 'units')).toBe('42 items'); // anyString() matches both // Override previous registration with same args (last-registered wins) calc.add.calledWith(1, 2).mockReturnValue(100); expect(calc.add(1, 2)).toBe(100); // overrides the earlier 3 // Async calledWith interface ApiClient { fetchData(id: string): Promise<{ value: number }>; } const client = mock(); client.fetchData.calledWith('abc').mockResolvedValue({ value: 42 }); await expect(client.fetchData('abc')).resolves.toEqual({ value: 42 }); // Used with jest.expect matchers too calc.add.calledWith(expect.any(Number), expect.any(Number)).mockReturnValue(0); expect(calc.add(3, 4)).toBe(0); ``` -------------------------------- ### captor() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt `captor()` is a special matcher that always returns `true` (matching any value) but also records every value it matched. Use `.value` for the last captured value and `.values` for all captured values across multiple calls. ```APIDOC ## `captor()` — Capture argument values from assertions `captor()` is a special matcher that always returns `true` (matching any value) but also records every value it matched. Use `.value` for the last captured value and `.values` for all captured values across multiple calls. ```typescript import { captor, any } from 'jest-mock-extended'; import { jest } from '@jest/globals'; interface EventEmitter { emit(event: string, payload: { userId: number; action: string }): void; } const emitter = { emit: jest.fn() }; // Simulate calls emitter.emit('login', { userId: 1, action: 'login' }); emitter.emit('login', { userId: 2, action: 'login' }); emitter.emit('logout', { userId: 1, action: 'logout' }); // Capture the payload argument across multiple calls const payloadCaptor = captor<{ userId: number; action: string }>(); expect(emitter.emit).toHaveBeenNthCalledWith(1, any(), payloadCaptor); expect(emitter.emit).toHaveBeenNthCalledWith(2, any(), payloadCaptor); expect(emitter.emit).toHaveBeenNthCalledWith(3, any(), payloadCaptor); // Last captured value expect(payloadCaptor.value).toEqual({ userId: 1, action: 'logout' }); // All captured values in order expect(payloadCaptor.values).toEqual([ { userId: 1, action: 'login' }, { userId: 2, action: 'login' }, { userId: 1, action: 'logout' }, ]); // Inspect specific captured values directly expect(payloadCaptor.values[0].userId).toBe(1); expect(payloadCaptor.values[1].userId).toBe(2); ``` ``` -------------------------------- ### Deep Mocking with Fallback Implementation Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Provide a fallback mock implementation for mockDeep to handle cases where return values are not explicitly defined using calledWith. This can be used to ensure all calls are intended. ```typescript import { mockDeep } from 'jest-mock-extended'; const mockObj = mockDeep({ fallbackMockImplementation: () => { throw new Error('please add expected return value using calledWith'); }, }); expect(() => mockObj.getNumber()).toThrowError('not mocked'); ``` -------------------------------- ### Reset Mock Implementations with mockReset Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `mockReset` to clear call history and all mock implementations, returning mocks to their initial unconfigured state. This is useful for ensuring test isolation, especially when using a `beforeEach` pattern. ```typescript import { mock, mockReset } from 'jest-mock-extended'; import { anyNumber } from 'jest-mock-extended'; interface PaymentService { charge(amount: number): boolean; refund(amount: number): boolean; } const payments = mock(); payments.charge.calledWith(anyNumber()).mockReturnValue(true); expect(payments.charge(100)).toBe(true); mockReset(payments); // All implementations cleared expect(payments.charge(100)).toBeUndefined(); // Re-setup after reset payments.charge.calledWith(50).mockReturnValue(true); payments.charge.calledWith(anyNumber()).mockReturnValue(false); expect(payments.charge(50)).toBe(true); expect(payments.charge(200)).toBe(false); // beforeEach pattern for test isolation describe('PaymentService tests', () => { const svc = mock(); beforeEach(() => mockReset(svc)); test('charge returns true for valid amount', () => { svc.charge.mockReturnValue(true); expect(svc.charge(99)).toBe(true); }); test('no leakage from previous test', () => { expect(svc.charge(99)).toBeUndefined(); }); }); ``` -------------------------------- ### JestMockExtended.configure(config) / JestMockExtended.resetConfig() Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Controls library-wide behavior such as which property names are silently ignored (return `undefined`) when accessed on any mock proxy. The default config ignores `'then'` to prevent mock objects from being treated as Promises. Always reset config in `afterEach` to prevent test pollution. ```APIDOC ## JestMockExtended.configure(config) / JestMockExtended.resetConfig() ### Description Controls library-wide behavior such as which property names are silently ignored (return `undefined`) when accessed on any mock proxy. The default config ignores `'then'` to prevent mock objects from being treated as Promises. ### Method `configure(config: object)`: Sets global configuration options. `resetConfig()`: Resets configuration to defaults. ### Parameters #### `configure` Method Parameters - **config** (object) - Required - An object containing configuration options. - **ignoreProps** (string[]) - Optional - An array of property names to ignore. ### Request Example ```typescript import { mock, JestMockExtended } from 'jest-mock-extended'; // Override: allow 'then' to be mocked JestMockExtended.configure({ ignoreProps: [] }); const thenMock = mock<{ then: () => void }>(); thenMock.then(); expect(thenMock.then).toHaveBeenCalled(); // Add custom props to ignore JestMockExtended.configure({ ignoreProps: ['then', 'toJSON', 'inspect'] }); const customMock = mock<{ then: () => void; toJSON: () => string; name: string }>(); expect(customMock.then).toBeUndefined(); expect(customMock.toJSON).toBeUndefined(); expect(customMock.name).toBeDefined(); // Always reset config in afterEach to prevent test pollution afterEach(() => { JestMockExtended.resetConfig(); }); // Verify reset restores default behavior JestMockExtended.resetConfig(); const resetMock = mock<{ then: () => void }>(); expect(resetMock.then).toBeUndefined(); // back to default ``` ### Response N/A (This method configures behavior, does not return a value.) ### Error Handling N/A ``` -------------------------------- ### Use calledWith() for Argument Matching Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Utilize the calledWith() extension for precise argument matching in mock expectations. It supports type checking even with matchers like any() and anyString(). ```typescript const provider = mock(); provider.getSongs.calledWith('disco party').mockReturnValue(['Dance the night away', 'Stayin Alive']); expect(provider.getSongs('disco party')).toEqual(['Dance the night away', 'Stayin Alive']); // Matchers provider.getSongs.calledWith(any()).mockReturnValue(['Saw her standing there']); provider.getSongs.calledWith(anyString()).mockReturnValue(['Saw her standing there']); ``` -------------------------------- ### Create Inline Custom Matchers with `matches(fn)` Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `matches(fn)` to create a one-off matcher from a predicate function. This is helpful for assertions where built-in matchers are insufficient. It can be combined with other matchers like `anyArray()`. ```typescript import { matches } from 'jest-mock-extended'; import { jest } from '@jest/globals'; interface ReportService { generate(title: string, data: number[]): string; } const fn = jest.fn(); fn('Q1 Report', [100, 200, 300]); fn('Q2 Report', [400, 500]); // Custom predicate: title must start with 'Q' expect(fn).toHaveBeenCalledWith( matches((title: string) => title.startsWith('Q')), anyArray() // combined with built-in matchers ); // Negative assertion expect(fn).not.toHaveBeenCalledWith( matches((title: string) => title.startsWith('Annual')), expect.anything() ); ``` ```typescript import { mock } from 'jest-mock-extended'; import { anyArray } from 'jest-mock-extended'; const svc = mock(); svc.generate .calledWith(matches((t) => t.length > 5), anyArray()) .mockReturnValue('Long title report'); expect(svc.generate('Q1 Summary', [1, 2])).toBe('Long title report'); expect(svc.generate('Q1', [1, 2])).toBeUndefined(); // title too short, no match ``` -------------------------------- ### mockClear(mock) Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Clears the call history (calls, instances, results) of a mock function or mock proxy without removing its implementations. ```APIDOC ## mockClear(mock) ### Description Clears `mock.calls`, `mock.instances`, and `mock.results` on every `jest.fn()` within the mock proxy (recursively for deep mocks), preserving any `calledWith` return value setup. ### Method Mock clearing utility ### Endpoint N/A (TypeScript/JavaScript API) ### Parameters - **mock** (object): The mock object or mock function to clear. ### Request Example ```typescript import { mock, mockClear } from 'jest-mock-extended'; import { anyNumber } from 'jest-mock-extended'; interface Counter { increment(by: number): number; } const counter = mock(); counter.increment.calledWith(anyNumber()).mockReturnValue(1); counter.increment(5); counter.increment(10); mockClear(counter); // Also works on plain jest.fn() const fn = jest.fn().mockReturnValue(42); fn(); mockClear(fn); ``` ### Response #### Success Response (N/A - performs an action) Clears the call history of the provided mock. #### Response Example N/A ``` -------------------------------- ### Assign Mocks with MockProxy Type Source: https://github.com/marchaos/jest-mock-extended/blob/master/README.md Use MockProxy<> to assign a mock to a variable that requires a specific type, ensuring type safety for mock APIs like calledWith(). ```typescript import { MockProxy, mock } from 'jest-mock-extended'; describe('test', () => { let myMock: MockProxy; beforeEach(() => { myMock = mock(); }) test(() => { myMock.calledWith(1).mockReturnValue(2); ... }) }); ``` -------------------------------- ### Configure Global Mock Behavior Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Use `JestMockExtended.configure` to change which properties are ignored by default. The default configuration ignores 'then' to prevent mock objects from being treated as Promises. Reset the configuration using `JestMockExtended.resetConfig()` in `afterEach` to maintain test isolation. ```typescript import { mock, JestMockExtended } from 'jest-mock-extended'; // Default: 'then' is ignored so mocks don't look like thenables const defaultMock = mock<{ then: () => void; data: string }>(); expect(defaultMock.then).toBeUndefined(); // ignored by default expect(defaultMock.data).toBeDefined(); // normal mock fn // Override: allow 'then' to be mocked JestMockExtended.configure({ ignoreProps: [] }); const thenMock = mock<{ then: () => void }>(); thenMock.then(); expect(thenMock.then).toHaveBeenCalled(); // now accessible // Add custom props to ignore JestMockExtended.configure({ ignoreProps: ['then', 'toJSON', 'inspect'] }); const customMock = mock<{ then: () => void; toJSON: () => string; name: string }>(); expect(customMock.then).toBeUndefined(); expect(customMock.toJSON).toBeUndefined(); expect(customMock.name).toBeDefined(); // Always reset config in afterEach to prevent test pollution afterEach(() => { JestMockExtended.resetConfig(); }); // Verify reset restores default behavior JestMockExtended.resetConfig(); const resetMock = mock<{ then: () => void }>(); expect(resetMock.then).toBeUndefined(); // back to default ``` -------------------------------- ### Type-Safe Argument Matchers with jest-mock-extended Source: https://context7.com/marchaos/jest-mock-extended/llms.txt Utilize built-in matchers like `any`, `isA`, `arrayIncludes`, `notNull`, etc., for type-safe argument matching in `calledWith()` and `toHaveBeenCalledWith()`. These matchers implement Jest's asymmetric matcher interface for flexible assertions. ```typescript import { any, anyBoolean, anyNumber, anyString, anyFunction, anySymbol, anyObject, anyArray, anyMap, anySet, isA, arrayIncludes, setHas, mapHas, objectContainsKey, objectContainsValue, notNull, notUndefined, notEmpty, } from 'jest-mock-extended'; import { mock } from 'jest-mock-extended'; interface DataProcessor { process(items: any[], config: object, label: string): string; validate(value: any): boolean; store(map: Map, set: Set): void; } const dp = mock(); // anyArray / anyObject / anyString dp.process.calledWith(anyArray(), anyObject(), anyString()).mockReturnValue('ok'); expect(dp.process([1, 2], { strict: true }, 'run')).toBe('ok'); // anyBoolean / anyNumber / anyFunction dp.validate.calledWith(anyBoolean()).mockReturnValue(true); dp.validate.calledWith(anyNumber()).mockReturnValue(true); dp.validate.calledWith(anyFunction()).mockReturnValue(false); expect(dp.validate(true)).toBe(true); expect(dp.validate(42)).toBe(true); expect(dp.validate(() => {})).toBe(false); // isA — instance check class Config {} dp.validate.calledWith(isA(Config)).mockReturnValue(true); expect(dp.validate(new Config())).toBe(true); expect(dp.validate({})).toBe(false); // arrayIncludes / mapHas / setHas / objectContainsKey / objectContainsValue dp.validate.calledWith(arrayIncludes('admin')).mockReturnValue(true); expect(dp.validate(['admin', 'user'])).toBe(true); dp.store.calledWith( mapHas('userId'), setHas('active') ).mockReturnValue(undefined); dp.store(new Map([['userId', 1]]), new Set(['active'])); expect(dp.store).toHaveBeenCalledWith(mapHas('userId'), setHas('active')); // notNull / notUndefined / notEmpty const fn = mock<{ run(x: any): void }>(); fn.run.calledWith(notNull()).mockReturnValue(undefined); fn.run.calledWith(notEmpty()).mockReturnValue(undefined); // Use in toHaveBeenCalledWith assertions const mockFn2 = mock<{ send(data: string[], count: number): void }>(); mockFn2.send(['a', 'b'], 2); expect(mockFn2.send).toHaveBeenCalledWith(anyArray(), anyNumber()); expect(mockFn2.send).toHaveBeenCalledWith(arrayIncludes('a'), 2); expect(mockFn2.send).not.toHaveBeenCalledWith(anyArray(), 99); ```