Install jest-mock-extended
masterInstall the package as a development dependency using npm or yarn.
npm install jest-mock-extended --save-devor
yarn add jest-mock-extended --devrepository·master·Indexed 21 days ago
https://github.com/marchaos/jest-mock-extendedType-safe mocking extensions for Jest (version 4.0.1) that provide full TypeScript support for mocking interfaces, objects, and classes. It includes utilities like mock() for shallow mocks, mockDeep() for nested hierarchies, and stub() for lightweight proxies. The library extends standard Jest mocks with the calledWith() method for argument-specific behavior and provides a comprehensive set of asymmetric matchers, captors, and state management functions like mockClear() and mockReset().
Install the package as a development dependency using npm or yarn.
npm install jest-mock-extended --save-devor
yarn add jest-mock-extended --devThe mockDeep function creates a DeepMockProxy<T>, where nested objects and functions are also automatically mocked. This is useful for complex, deeply nested dependency trees.
There are two ways to call mockDeep:
mockDeep<T>(mockImplementation?: DeepPartial<T>): Pass a partial implementation of the object.mockDeep<T>(opts: { funcPropSupport?: true; fallbackMockImplementation?: MockOpts['fallbackMockImplementation'] }, mockImplementation?: DeepPartial<T>): Pass configuration options first.Note on funcPropSupport: When funcPropSupport is set to true, properties that are functions in the original type are treated as both a CalledWithMock and a DeepMockProxy, allowing for more flexible nested mocking.
import { mockDeep } from 'jest-mock-extended';
interface DeepService {
client: {
connection: {
query: () => Promise<string>;
};
};
}
const service = mockDeep<DeepService>();
// Deeply nested properties are automatically mocked
service.client.connection.query.mockResolvedValue('success');When using jest-mock-extended, you can use asymmetric matchers to validate that a mock was called with specific types or patterns rather than exact values. These matchers are passed into Jest's expectation functions (like toHaveBeenCalledWith).
Available matchers include:
any(), anyBoolean(), anyNumber(), anyString(), anyFunction(), anySymbol(), anyObject(), anyArray(), anyMap(), anySet().isA(Class) checks if a value is an instance of a specific class.arrayIncludes(value), setHas(value), mapHas(value), objectContainsKey(key), objectContainsValue(value).notNull(), notUndefined(), notEmpty().matches(matcherFn) allows you to provide a custom predicate function.import { anyString, isA, arrayIncludes } from 'jest-mock-extended';
// Example usage in a Jest test
expect(mock.method).toHaveBeenCalledWith(anyString());
expect(mock.method).toHaveBeenCalledWith(isA(MyClass));
expect(mock.method).toHaveBeenCalledWith(arrayIncludes('expected-item'));Use mockDeep() to create a mock object where all nested properties and methods are also automatically mocked. This returns a DeepMockProxy, which is useful for complex objects with deep hierarchies where you want to avoid manually mocking every sub-property.
import { mockDeep } from 'jest-mock-extended';
const deepMock = mockDeep<ComplexType>();
// deepMock.nestedProperty.method() is also a mockThe calledWithFn utility allows you to define different mock implementations based on the specific arguments passed to a function. Instead of a single global mock implementation, you can chain .calledWith(...) calls to return different values or execute different logic for specific argument sets.
When a call matches a previously defined set of arguments (using either literal values or matchers), the specific mock associated with those arguments is executed. If no match is found, the fallbackMockImplementation (if provided) is used.
import { calledWithFn } from 'jest-mock-extended';
// Example usage pattern:
const myMock = calledWithFn((arg: string) => `Hello ${arg}`);
// You can define specific behaviors for specific arguments
myMock.calledWith('world')();
// When called with 'world', it uses the specific mock returned by .calledWith()
// When called with anything else, it falls back to the original implementationThe stub<T>() function creates a proxy of type T. Unlike mock(), it does not create complex Jest mocks for every property. Instead, if you access a property that does not exist on the object, it returns a jest.fn(). This is useful for lightweight stubs where you only care about a few specific method calls.
import { stub } from 'jest-mock-extended';
interface Simple {
doSomething: () => void;
}
const s = stub<Simple>();
// s.doSomething is a jest.fn()
s.doSomething();The mock function creates a MockProxy<T>. This proxy automatically mocks all properties of the type T. If a property is a function, it is automatically turned into a Jest mock function with the calledWith extension.
mock(mockImplementation?: DeepPartial<T>, opts?: MockOpts)opts.deep: (Boolean) If true, enables deep mocking (see mockDeep).opts.fallbackMockImplementation: (Function) A function to provide a default implementation for mocked properties.import { mock } from 'jest-mock-extended';
interface User {
id: string;
getName: () => string;
}
const userMock = mock<User>();
// userMock.getName is now a jest.fn()
userMock.getName.mockReturnValue('John Doe');If the built-in matchers do not satisfy your requirements, you can create a custom matcher using the matches() function. This function accepts a predicate function (a MatcherFn<T>) that returns true if the value matches your criteria.
matches<T>((actualValue: T) => boolean)
import { matches } from 'jest-mock-extended';
// Create a matcher that checks if a string starts with a specific prefix
const startsWithHello = matches((val: string) => val.startsWith('Hello'));
expect(mock.method).toHaveBeenCalledWith(startsWithHello());These utilities allow you to recursively clear or reset all mock state within a MockProxy or DeepMockProxy.
mockClear(mock: MockProxy<any>): Clears the state of all mock functions (calls, instances, etc.) within the proxy and its nested mocks.mockReset(mock: MockProxy<any>): Resets all mock functions to their initial state (removes any mocked implementations) within the proxy and its nested mocks.import { mock, mockClear, mockReset } from 'jest-mock-extended';
const service = mock<MyService>();
// ... perform tests ...
mockClear(service); // Clears call history
mockReset(service); // Clears history AND implementationsThe captor() utility allows you to both validate an argument in an expectation and extract the actual value(s) passed to a mock for further assertions.
A CaptorMatcher acts as an asymmetric matcher that, when matched, stores the actualValue in its .value property and pushes all matched values into its .values array.
Use this when you need to perform complex assertions on the arguments that are difficult to express with standard matchers.
import { captor } from 'jest-mock-extended';
const myCaptor = captor<MyType>();
// Use the captor in the expectation
expect(mock.method).toHaveBeenCalledWith(myCaptor());
// Access the captured values for detailed assertions
const capturedValue = myCaptor.value;
const allCapturedValues = myCaptor.values;
expect(capturedValue.someProperty).toBe('specific-value');Use JestMockExtended.configure to set global configuration for mocks. A common use case is using ignoreProps to prevent the mock from returning values for specific properties (e.g., when mocking a Promise, you might want to ignore then to avoid unexpected behavior).
configure(config: GlobalConfig): Performs a shallow merge of your config with the DEFAULT_CONFIG.resetConfig(): Resets the global configuration to DEFAULT_CONFIG.DEFAULT_CONFIG: Contains { ignoreProps: ['then'] } by default.import { JestMockExtended } from 'jest-mock-extended';
JestMockExtended.configure({
ignoreProps: ['then', 'someOtherProp']
});
// To revert to defaults
JestMockExtended.resetConfig();To maintain clean tests, you can manage the state of your mocks using these utility functions:
mockClear(mock): Clears the state of the mock (e.g., call history, instances) but keeps the implementation/return values intact.mockReset(mock): Resets the mock to its initial state, clearing both the call history and any mocked implementations/return values.import { mockClear, mockReset } from 'jest-mock-extended';
const myMock = mock<MyType>();
// After some interactions:
mockClear(myMock);
// or
mockReset(myMock);