Type safe mocking extensions for jest
npx @tessl/cli install tessl/npm-jest-mock-extended@4.0.0Jest Mock Extended provides comprehensive type-safe mocking extensions for the Jest testing framework. It enables developers to create fully typed mock objects for interfaces and classes with complete TypeScript type safety, offering advanced mocking capabilities including argument-specific expectations, deep object mocking, and extensive matcher API.
npm install jest-mock-extended --save-devimport {
mock,
mockDeep,
MockProxy,
DeepMockProxy,
DeepMockProxyWithFuncPropSupport,
any,
anyString,
anyNumber
} from "jest-mock-extended";For CommonJS:
const { mock, mockDeep, any, anyString, anyNumber } = require("jest-mock-extended");import { mock, MockProxy } from "jest-mock-extended";
interface UserService {
getUser: (id: string) => Promise<User>;
deleteUser: (id: string) => void;
}
// Create a type-safe mock
const userService: MockProxy<UserService> = mock<UserService>();
// Set up expectations with argument matching
userService.getUser.calledWith("123").mockResolvedValue({ id: "123", name: "John" });
// Use in tests
test("should get user", async () => {
const result = await userService.getUser("123");
expect(result).toEqual({ id: "123", name: "John" });
expect(userService.getUser).toHaveBeenCalledWith("123");
});Jest Mock Extended is built around several key components:
calledWith() extension for creating expectations based on specific argument patternsCore mock creation functionality for interfaces and classes with full TypeScript type safety and Jest integration.
function mock<T>(
mockImplementation?: DeepPartial<T>,
opts?: MockOpts
): MockProxy<T> & T;
interface MockProxy<T> {
[K in keyof T]: T[K] extends FunctionLike
? T[K] & CalledWithMock<T[K]>
: T[K];
}
interface MockOpts {
deep?: boolean;
fallbackMockImplementation?: (...args: any[]) => any;
}Advanced mocking capabilities for nested objects and complex data structures with recursive type-safe mocking.
function mockDeep<T>(
opts: {
funcPropSupport?: true;
fallbackMockImplementation?: MockOpts['fallbackMockImplementation']
},
mockImplementation?: DeepPartial<T>
): DeepMockProxyWithFuncPropSupport<T>;
function mockDeep<T>(mockImplementation?: DeepPartial<T>): DeepMockProxy<T>;
type DeepMockProxy<T> = _DeepMockProxy<T> & T;Sophisticated argument matching system with calledWith() extension for creating expectations based on specific argument patterns.
interface CalledWithMock<T extends FunctionLike> extends jest.Mock<T> {
calledWith: (...args: [...MatchersOrLiterals<Parameters<T>>]) => jest.Mock<T>;
}
function mockFn<T extends FunctionLike>(): CalledWithMock<T> & T;
function calledWithFn<T extends FunctionLike>(
options?: { fallbackMockImplementation?: T }
): CalledWithMock<T>;Extensive built-in matcher system with type-safe argument validation and support for custom matcher creation.
class Matcher<T> implements MatcherLike<T> {
constructor(asymmetricMatch: MatcherFn<T>, description: string);
asymmetricMatch(other: unknown): boolean;
toString(): string;
}
// Built-in matchers
function any<T>(): Matcher<T>;
function anyString(): Matcher<string>;
function anyNumber(): Matcher<number>;
function anyBoolean(): Matcher<boolean>;Mock management utilities for clearing, resetting, and configuring mock behavior globally.
function mockClear(mock: MockProxy<any>): void;
function mockReset(mock: MockProxy<any>): void;
function stub<T extends object>(): T;
interface GlobalConfig {
ignoreProps?: ProxiedProperty[];
}
const JestMockExtended: {
DEFAULT_CONFIG: GlobalConfig;
configure: (config: GlobalConfig) => void;
resetConfig: () => void;
};interface MockOpts {
/** Enable deep mocking for nested objects */
deep?: boolean;
/** Fallback implementation when no expectation is set */
fallbackMockImplementation?: (...args: any[]) => any;
}
interface CalledWithMock<T extends FunctionLike> extends jest.Mock<T> {
calledWith: (...args: [...MatchersOrLiterals<Parameters<T>>]) => jest.Mock<T>;
}
type MatchersOrLiterals<Y extends any[]> = {
[K in keyof Y]: MatcherLike<Y[K]> | Y[K]
};
type MatcherFn<T> = (actualValue: T) => boolean;
interface MatcherCreator<T, E = T> {
(expectedValue?: E): Matcher<T>;
}
interface MatcherLike<T> {
asymmetricMatch(other: unknown): boolean;
toString(): string;
getExpectedType?(): string;
toAsymmetricMatcher?(): string;
}
class Matcher<T> implements MatcherLike<T> {
$$typeof: symbol;
inverse?: boolean;
constructor(readonly asymmetricMatch: MatcherFn<T>, readonly description: string);
toString(): string;
toAsymmetricMatcher(): string;
getExpectedType(): string;
}
class CaptorMatcher<T> {
$$typeof: symbol;
readonly asymmetricMatch: MatcherFn<T>;
readonly value: T;
readonly values: T[];
constructor();
getExpectedType(): string;
toString(): string;
toAsymmetricMatcher(): string;
}
type ProxiedProperty = string | number | symbol;
// From jest-mock dependency
type FunctionLike = (...args: any[]) => any;
type _MockProxy<T> = {
[K in keyof T]: T[K] extends FunctionLike
? T[K] & CalledWithMock<T[K]>
: T[K];
};
type MockProxy<T> = _MockProxy<T> & T;
type _DeepMockProxy<T> = {
[K in keyof T]: T[K] extends FunctionLike
? T[K] & CalledWithMock<T[K]>
: T[K] & _DeepMockProxy<T[K]>;
};
type DeepMockProxy<T> = _DeepMockProxy<T> & T;
type _DeepMockProxyWithFuncPropSupport<T> = {
[K in keyof T]: T[K] extends FunctionLike
? CalledWithMock<T[K]> & DeepMockProxy<T[K]>
: DeepMockProxy<T[K]>;
};
type DeepMockProxyWithFuncPropSupport<T> = _DeepMockProxyWithFuncPropSupport<T> & T;