CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jest-mock-extended

Type safe mocking extensions for jest

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

deep-mocking.mddocs/

Deep Mocking

Advanced mocking capabilities for nested objects and complex data structures with recursive type-safe mocking.

Capabilities

Deep Mock Function

Creates a deep mock proxy that recursively mocks nested objects and properties, maintaining type safety throughout the entire object hierarchy.

/**
 * Creates deep mock with function property support
 * @param opts - Configuration options including function property support
 * @param mockImplementation - Optional partial implementation
 * @returns Deep mock proxy with function property support
 */
function mockDeep<T>(
  opts: { 
    funcPropSupport?: true; 
    fallbackMockImplementation?: MockOpts['fallbackMockImplementation'] 
  },
  mockImplementation?: DeepPartial<T>
): DeepMockProxyWithFuncPropSupport<T>;

/**
 * Creates standard deep mock proxy
 * @param mockImplementation - Optional partial implementation
 * @returns Deep mock proxy for nested object mocking
 */
function mockDeep<T>(mockImplementation?: DeepPartial<T>): DeepMockProxy<T>;

Usage Examples:

import { mockDeep, DeepMockProxy } from "jest-mock-extended";

interface Database {
  users: {
    findById: (id: string) => Promise<User>;
    create: (user: CreateUserData) => Promise<User>;
    repository: {
      query: (sql: string) => Promise<any[]>;
      transaction: {
        begin: () => Promise<void>;
        commit: () => Promise<void>;
        rollback: () => Promise<void>;
      };
    };
  };
  products: {
    findAll: () => Promise<Product[]>;
    findByCategory: (category: string) => Promise<Product[]>;
  };
}

// Standard deep mocking
const database: DeepMockProxy<Database> = mockDeep<Database>();

// Set up nested expectations
database.users.findById.calledWith("123").mockResolvedValue({
  id: "123",
  name: "John Doe"
});

database.users.repository.query
  .calledWith("SELECT * FROM users")
  .mockResolvedValue([{ id: "123" }]);

// Deep mocking with function property support
const advancedDatabase = mockDeep<Database>({ funcPropSupport: true });

// Can mock both function calls and function properties
advancedDatabase.users.repository.calledWith("custom").mockReturnValue("result");
advancedDatabase.users.repository.query.calledWith("SELECT").mockResolvedValue([]);

DeepMockProxy Type

Type definition for deep mock proxies that recursively applies mocking to nested object properties.

/**
 * Deep mock proxy type for recursive mocking of nested objects
 */
type DeepMockProxy<T> = _DeepMockProxy<T> & T;

type _DeepMockProxy<T> = {
  [K in keyof T]: T[K] extends FunctionLike
    ? T[K] & CalledWithMock<T[K]>
    : T[K] & _DeepMockProxy<T[K]>;
};

Usage Examples:

import { mockDeep, DeepMockProxy } from "jest-mock-extended";

interface ApiClient {
  auth: {
    login: (credentials: LoginCredentials) => Promise<AuthToken>;
    logout: () => Promise<void>;
    refresh: (token: string) => Promise<AuthToken>;
  };
  data: {
    users: {
      get: (id: string) => Promise<User>;
      list: (params: ListParams) => Promise<User[]>;
    };
    posts: {
      get: (id: string) => Promise<Post>;
      create: (post: CreatePost) => Promise<Post>;
    };
  };
}

const apiClient: DeepMockProxy<ApiClient> = mockDeep<ApiClient>();

// All nested properties are automatically mocked
apiClient.auth.login.mockResolvedValue({ token: "abc123" });
apiClient.data.users.get.calledWith("user1").mockResolvedValue({ id: "user1" });
apiClient.data.posts.list.mockResolvedValue([]);

DeepMockProxyWithFuncPropSupport Type

Extended deep mock proxy that supports both function calls and function properties, useful for objects that have functions with additional function properties.

/**
 * Deep mock proxy with support for function properties
 */
type DeepMockProxyWithFuncPropSupport<T> = _DeepMockProxyWithFuncPropSupport<T> & T;

type _DeepMockProxyWithFuncPropSupport<T> = {
  [K in keyof T]: T[K] extends FunctionLike
    ? CalledWithMock<T[K]> & DeepMockProxy<T[K]>
    : DeepMockProxy<T[K]>;
};

Usage Examples:

import { mockDeep } from "jest-mock-extended";

interface Logger {
  log: {
    (message: string): void;
    error: (error: Error) => void;
    warn: (warning: string) => void;
    debug: {
      (message: string): void;
      verbose: (details: any) => void;
    };
  };
}

// Enable function property support
const logger = mockDeep<Logger>({ funcPropSupport: true });

// Mock the main function
logger.log.calledWith("info message").mockReturnValue(undefined);

// Mock function properties  
logger.log.error.calledWith(expect.any(Error)).mockReturnValue(undefined);
logger.log.debug.calledWith("debug info").mockReturnValue(undefined);
logger.log.debug.verbose.calledWith(expect.any(Object)).mockReturnValue(undefined);

// Test usage
logger.log("info message");
logger.log.error(new Error("test error"));
logger.log.debug("debug info");
logger.log.debug.verbose({ details: "verbose logging" });

Deep Mock with Fallback Implementation

Deep mocking with fallback implementation for handling unmocked function calls.

Usage Examples:

import { mockDeep } from "jest-mock-extended";

interface ComplexService {
  cache: {
    get: (key: string) => any;
    set: (key: string, value: any) => void;
    nested: {
      clear: () => void;
      stats: () => { hits: number; misses: number };
    };
  };
}

// Deep mock with strict fallback
const service = mockDeep<ComplexService>({
  fallbackMockImplementation: () => {
    throw new Error("Please add expected return value using calledWith");
  }
});

// Set up specific expectations
service.cache.get.calledWith("user:123").mockReturnValue({ name: "John" });
service.cache.nested.stats.mockReturnValue({ hits: 10, misses: 2 });

// These will work
expect(service.cache.get("user:123")).toEqual({ name: "John" });
expect(service.cache.nested.stats()).toEqual({ hits: 10, misses: 2 });

// This will throw the fallback error
expect(() => service.cache.get("unmocked:key")).toThrow("Please add expected return value");

docs

argument-matching.md

basic-mocking.md

deep-mocking.md

index.md

matchers.md

utilities.md

tile.json