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

utilities.mddocs/

Utilities

Mock management utilities for clearing, resetting, and configuring mock behavior globally.

Capabilities

Mock Clearing

Recursively clears all mock calls and instances while preserving configured expectations and return values.

/**
 * Recursively clears all mock calls and instances
 * @param mock - Mock proxy to clear (can be nested)
 */
function mockClear(mock: MockProxy<any>): void;

Usage Examples:

import { mock, mockClear, MockProxy } from "jest-mock-extended";

interface UserService {
  getUser: (id: string) => Promise<User>;
  updateUser: (id: string, data: UserData) => Promise<User>;
  nested: {
    cache: {
      get: (key: string) => any;
      set: (key: string, value: any) => void;
    };
  };
}

describe("UserService tests", () => {
  let userService: MockProxy<UserService>;

  beforeEach(() => {
    userService = mock<UserService>();
    
    // Set up expectations
    userService.getUser.calledWith("123").mockResolvedValue({ id: "123", name: "John" });
    userService.nested.cache.get.calledWith("user:123").mockReturnValue({ cached: true });
  });

  afterEach(() => {
    // Clear all calls but keep expectations
    mockClear(userService);
  });

  test("first test", async () => {
    await userService.getUser("123");
    userService.nested.cache.get("user:123");
    
    expect(userService.getUser).toHaveBeenCalledTimes(1);
    expect(userService.nested.cache.get).toHaveBeenCalledTimes(1);
  });

  test("second test", async () => {
    // Calls were cleared, but expectations remain
    expect(userService.getUser).toHaveBeenCalledTimes(0);
    expect(userService.nested.cache.get).toHaveBeenCalledTimes(0);
    
    // Expectations still work
    const result = await userService.getUser("123");
    expect(result).toEqual({ id: "123", name: "John" });
  });
});

Mock Resetting

Recursively resets all mock calls, instances, and return values, completely clearing all mock state.

/**
 * Recursively resets all mock calls, instances, and return values
 * @param mock - Mock proxy to reset (can be nested)
 */
function mockReset(mock: MockProxy<any>): void;

Usage Examples:

import { mock, mockReset, MockProxy } from "jest-mock-extended";

interface ApiClient {
  request: (method: string, url: string) => Promise<any>;
  auth: {
    login: (credentials: LoginData) => Promise<AuthToken>;
    logout: () => Promise<void>;
  };
}

describe("ApiClient tests", () => {
  let apiClient: MockProxy<ApiClient>;

  beforeEach(() => {
    apiClient = mock<ApiClient>();
  });

  test("test with fresh mock", () => {
    // Set up expectations for this test
    apiClient.request.calledWith("GET", "/users").mockResolvedValue([]);
    apiClient.auth.login.mockResolvedValue({ token: "abc123" });

    // Use the mock
    expect(apiClient.request("GET", "/users")).resolves.toEqual([]);
    expect(apiClient.auth.login({ username: "user", password: "pass" }))
      .resolves.toEqual({ token: "abc123" });
  });

  test("test with completely reset mock", () => {
    // Set up some expectations
    apiClient.request.mockResolvedValue("initial");
    apiClient.auth.logout.mockResolvedValue(undefined);

    // Use the mock
    expect(apiClient.request("POST", "/data")).resolves.toBe("initial");

    // Completely reset the mock - clears all calls and expectations
    mockReset(apiClient);

    // Mock is now completely clean
    expect(apiClient.request).toHaveBeenCalledTimes(0);
    expect(apiClient.auth.logout).toHaveBeenCalledTimes(0);

    // Need to set up new expectations
    apiClient.request.calledWith("GET", "/fresh").mockResolvedValue("fresh data");
    expect(apiClient.request("GET", "/fresh")).resolves.toBe("fresh data");
  });
});

Stub Creation

Creates a simple stub object that returns jest.fn() for any property access, useful for basic mocking scenarios.

/**
 * Creates a stub that returns jest.fn() for any property access
 * @returns Stub object with dynamic jest.fn() properties
 */
function stub<T extends object>(): T;

Usage Examples:

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

interface Logger {
  info: (message: string) => void;
  warn: (message: string) => void;
  error: (message: string) => void;
  debug: (message: string) => void;
}

// Create a simple stub
const logger = stub<Logger>();

// All properties return jest.fn() automatically
logger.info("test message");
logger.error("error message");

// Can set up expectations like regular jest.fn()
logger.warn.mockImplementation((msg) => console.log(`WARN: ${msg}`));

// Verify calls
expect(logger.info).toHaveBeenCalledWith("test message");
expect(logger.error).toHaveBeenCalledWith("error message");

// Example usage in dependency injection
class UserService {
  constructor(private logger: Logger) {}

  createUser(userData: any) {
    this.logger.info("Creating user");
    // ... user creation logic
    this.logger.info("User created successfully");
  }
}

const userService = new UserService(stub<Logger>());
userService.createUser({ name: "John" });

// Verify logging calls were made
expect(userService['logger'].info).toHaveBeenCalledTimes(2);

Global Configuration

System for configuring global mock behavior across your entire test suite.

/**
 * Global configuration interface for mock behavior
 */
interface GlobalConfig {
  /** Properties to ignore when creating mock proxies */
  ignoreProps?: ProxiedProperty[];
}

/**
 * Configuration object for global mock settings
 */
const JestMockExtended: {
  /** Default configuration object */
  DEFAULT_CONFIG: GlobalConfig;
  
  /**
   * Configure global mock behavior
   * @param config - Configuration options to apply globally
   */
  configure: (config: GlobalConfig) => void;
  
  /** Reset configuration to default values */
  resetConfig: () => void;
};

type ProxiedProperty = string | number | symbol;

Usage Examples:

import { JestMockExtended, mock } from "jest-mock-extended";

// Default configuration includes ignoring 'then' property for promise handling
interface AsyncService {
  fetchData: () => Promise<any>;
  processData: (data: any) => Promise<void>;
}

// Configure global settings before tests
beforeAll(() => {
  JestMockExtended.configure({
    ignoreProps: ['then', 'catch', 'finally', 'constructor']
  });
});

afterAll(() => {
  // Reset to defaults after tests
  JestMockExtended.resetConfig();
});

test("mock with global config", () => {
  const service = mock<AsyncService>();
  
  // 'then' property is ignored and returns undefined
  expect(service.then).toBeUndefined();
  
  // Regular mocking still works
  service.fetchData.mockResolvedValue({ data: "test" });
  expect(service.fetchData()).resolves.toEqual({ data: "test" });
});

// Example: Ignoring specific framework properties
interface ReactComponent {
  render: () => JSX.Element;
  componentDidMount: () => void;
  setState: (state: any) => void;
  // React internals that shouldn't be mocked
  _reactInternalFiber?: any;
  _reactInternalInstance?: any;
}

beforeEach(() => {
  JestMockExtended.configure({
    ignoreProps: [
      'then', // Default for promises
      '_reactInternalFiber',
      '_reactInternalInstance',
      '$$typeof'
    ]
  });
});

test("React component mock", () => {
  const component = mock<ReactComponent>();
  
  // Internal React properties are ignored
  expect(component._reactInternalFiber).toBeUndefined();
  expect(component._reactInternalInstance).toBeUndefined();
  
  // Regular component methods work
  component.render.mockReturnValue(<div>Test</div>);
  component.componentDidMount.mockImplementation(() => {});
  
  expect(component.render()).toEqual(<div>Test</div>);
});

// Temporary configuration changes
test("temporary config override", () => {
  // Save current config
  const originalConfig = JestMockExtended.DEFAULT_CONFIG;
  
  // Apply temporary config
  JestMockExtended.configure({
    ignoreProps: ['customProperty', 'tempProp']
  });
  
  const testMock = mock<{ customProperty: string; normalProp: string }>();
  
  expect(testMock.customProperty).toBeUndefined();
  expect(typeof testMock.normalProp).toBe('function'); // Mock function created
  
  // Restore original config
  JestMockExtended.resetConfig();
});

docs

argument-matching.md

basic-mocking.md

deep-mocking.md

index.md

matchers.md

utilities.md

tile.json