CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jest-mock

Comprehensive mock function library providing sophisticated mocking, spying, and property replacement capabilities for JavaScript and TypeScript testing

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

advanced-mock-generation.mddocs/

Advanced Mock Generation

Low-level ModuleMocker class providing metadata-driven mock generation and advanced mocking scenarios for complex use cases.

Capabilities

ModuleMocker Class

Core class for advanced mock generation with full control over mock creation and management.

/**
 * Low-level mock generation class for advanced scenarios
 */
class ModuleMocker {
  /**
   * Creates a new ModuleMocker instance
   * @param global - Global object of the environment (e.g., globalThis, window)
   */
  constructor(global: typeof globalThis);

  /**
   * Creates a mock function with optional implementation
   * @param implementation - Optional function implementation
   * @returns Mock function with tracking capabilities
   */
  fn<T extends FunctionLike = UnknownFunction>(implementation?: T): Mock<T>;

  /**
   * Creates a spy on an object method or property
   * @param object - Target object
   * @param methodKey - Method or property key to spy on
   * @param accessType - For properties, specify 'get' or 'set'
   * @returns MockInstance for the spied target
   */
  spyOn<T extends object, K extends keyof T>(
    object: T,
    methodKey: K,
    accessType?: 'get' | 'set'
  ): MockInstance;

  /**
   * Temporarily replaces an object property
   * @param object - Target object
   * @param propertyKey - Property key to replace
   * @param value - New property value
   * @returns Replaced instance with control methods
   */
  replaceProperty<T extends object, K extends keyof T>(
    object: T,
    propertyKey: K,
    value: T[K]
  ): Replaced<T[K]>;

  /**
   * Type assertion utility for mocked objects
   * @param source - Object to assert as mocked
   * @param options - Shallow or deep mocking options
   * @returns Type-asserted mocked object
   */
  mocked<T extends object>(source: T, options?: {shallow?: boolean}): Mocked<T> | MockedShallow<T>;

  /**
   * Checks if a function is a mock function
   * @param fn - Function to check
   * @returns True if function is a mock
   */
  isMockFunction(fn: unknown): fn is Mock<UnknownFunction>;

  /**
   * Clears call history for all mocks created by this instance
   */
  clearAllMocks(): void;

  /**
   * Resets all mocks created by this instance to default state
   */
  resetAllMocks(): void;

  /**
   * Restores all spies created by this instance
   */
  restoreAllMocks(): void;
}

type FunctionLike = (...args: any) => any;
type UnknownFunction = (...args: Array<unknown>) => unknown;

Usage Examples:

import { ModuleMocker } from "jest-mock";

// Create a module mocker for specific environment
const mocker = new ModuleMocker(globalThis);

// Create mock functions
const mockFn = mocker.fn((x: number) => x * 2);
console.log(mockFn(5)); // 10

// Create spies
const obj = { method: () => 'original' };
const spy = mocker.spyOn(obj, 'method');
spy.mockReturnValue('mocked');

// Bulk operations
mocker.clearAllMocks();
mocker.restoreAllMocks();

Metadata-Driven Mock Generation

Generate mocks from metadata schemas describing object structure and behavior.

/**
 * Generates a mock from metadata schema
 * @param metadata - Object metadata in schema format
 * @returns Generated mock object
 */
generateFromMetadata<T>(metadata: MockMetadata<T>): Mocked<T>;

/**
 * Extracts metadata schema from existing object
 * @param component - Object to analyze
 * @param _refs - Internal reference tracking (optional)
 * @returns Metadata schema or null if not mockable
 */
getMetadata<T = unknown>(component: T, _refs?: Map<T, number>): MockMetadata<T> | null;

/**
 * Metadata schema format for mock generation
 */
interface MockMetadata<T, MetadataType = MockMetadataType> {
  /** Reference ID for circular references */
  ref?: number;
  /** Nested object member metadata */
  members?: Record<string, MockMetadata<T>>;
  /** Mock implementation for functions */
  mockImpl?: T;
  /** Function name */
  name?: string;
  /** Unique reference identifier */
  refID?: number;
  /** Type of the metadata */
  type?: MetadataType;
  /** Constant value */
  value?: T;
  /** Function arity (parameter count) */
  length?: number;
}

type MockMetadataType = 
  | 'object' 
  | 'array' 
  | 'regexp' 
  | 'function' 
  | 'constant' 
  | 'collection' 
  | 'null' 
  | 'undefined';

Usage Examples:

import { ModuleMocker } from "jest-mock";

const mocker = new ModuleMocker(globalThis);

// Extract metadata from existing object
const originalObject = {
  name: 'example',
  calculate: (a: number, b: number) => a + b,
  nested: {
    value: 42,
    transform: (x: number) => x * 2
  }
};

const metadata = mocker.getMetadata(originalObject);
console.log(metadata?.type); // 'object'
console.log(metadata?.members?.calculate?.type); // 'function'

// Generate mock from metadata
const mockObject = mocker.generateFromMetadata(metadata!);
console.log(mocker.isMockFunction(mockObject.calculate)); // true
console.log(mocker.isMockFunction(mockObject.nested.transform)); // true

// Use generated mocks
mockObject.calculate.mockReturnValue(100);
console.log(mockObject.calculate(1, 2)); // 100

Manual Metadata Creation

Create metadata schemas manually for custom mock generation.

// Create metadata for a function
const functionMetadata: MockMetadata<(x: number) => string> = {
  type: 'function',
  name: 'myFunction',
  length: 1
};

// Create metadata for an object with methods
const objectMetadata: MockMetadata<any> = {
  type: 'object',
  members: {
    method1: {
      type: 'function',
      name: 'method1',
      length: 2
    },
    property1: {
      type: 'constant',
      value: 'test'
    },
    nested: {
      type: 'object',
      members: {
        innerMethod: {
          type: 'function',
          name: 'innerMethod'
        }
      }
    }
  }
};

const mock = mocker.generateFromMetadata(objectMetadata);
// mock.method1 is a mock function
// mock.property1 is 'test'  
// mock.nested.innerMethod is a mock function

Circular Reference Handling

Handle objects with circular references using ref/refID system.

// Metadata with circular reference
const circularMetadata: MockMetadata<any> = {
  type: 'object',
  refID: 1,
  members: {
    name: {
      type: 'constant',
      value: 'circular'
    },
    self: {
      ref: 1  // References the object with refID: 1
    }
  }
};

const circularMock = mocker.generateFromMetadata(circularMetadata);
console.log(circularMock.self === circularMock); // true

Mock Detection and Management

Utilities for detecting and managing mock functions.

/**
 * Type guard to check if a value is a mock function
 * @param fn - Value to check
 * @returns True if value is a mock function
 */
isMockFunction<T extends FunctionLike = UnknownFunction>(fn: MockInstance<T>): fn is MockInstance<T>;
isMockFunction<P extends Array<unknown>, R>(fn: (...args: P) => R): fn is Mock<(...args: P) => R>;
isMockFunction(fn: unknown): fn is Mock<UnknownFunction>;

/**
 * Clears call history for all mocks created by this ModuleMocker
 */
clearAllMocks(): void;

/**
 * Resets all mocks created by this ModuleMocker to default state
 */
resetAllMocks(): void;

/**
 * Restores all spies created by this ModuleMocker
 */
restoreAllMocks(): void;

Usage Examples:

import { ModuleMocker } from "jest-mock";

const mocker = new ModuleMocker(globalThis);

// Create various mocks
const fn1 = mocker.fn();
const fn2 = mocker.fn();
const obj = { method: () => 'original' };
const spy = mocker.spyOn(obj, 'method');

// Check if functions are mocks
console.log(mocker.isMockFunction(fn1)); // true
console.log(mocker.isMockFunction(obj.method)); // true (after spying)
console.log(mocker.isMockFunction(() => {})); // false

// Call mocks to create history
fn1('test');
fn2(1, 2, 3);
obj.method();

// Bulk operations
mocker.clearAllMocks(); // Clears call history but preserves implementations
console.log(fn1.mock.calls.length); // 0

mocker.resetAllMocks(); // Clears history AND implementations
console.log(fn1()); // undefined (implementation cleared)

mocker.restoreAllMocks(); // Restores original implementations for spies
console.log(obj.method()); // 'original' (restored)

Environment-Specific Mocking

Create mocks for different JavaScript environments.

// Browser environment
const browserMocker = new ModuleMocker(window);

// Node.js environment  
const nodeMocker = new ModuleMocker(globalThis);

// Custom environment
const customGlobal = {
  Object: Object,
  Function: Function,
  Array: Array,
  RegExp: RegExp,
  Promise: Promise
};
const customMocker = new ModuleMocker(customGlobal as any);

Advanced Usage Patterns

Mock Factory Pattern

import { ModuleMocker } from "jest-mock";

class MockFactory {
  private mocker = new ModuleMocker(globalThis);
  
  createMockService<T extends object>(Service: new () => T): T {
    const instance = new Service();
    const metadata = this.mocker.getMetadata(instance);
    return this.mocker.generateFromMetadata(metadata!) as T;
  }
  
  cleanup() {
    this.mocker.restoreAllMocks();
    this.mocker.clearAllMocks();
  }
}

// Usage
const factory = new MockFactory();
const mockService = factory.createMockService(MyService);
// All methods of MyService are now mocked

Metadata Transformation

import { ModuleMocker, MockMetadata } from "jest-mock";

function addMockImplementation<T>(
  metadata: MockMetadata<T>, 
  implementations: Record<string, Function>
): MockMetadata<T> {
  if (metadata.members) {
    for (const [key, member] of Object.entries(metadata.members)) {
      if (member.type === 'function' && implementations[key]) {
        member.mockImpl = implementations[key] as any;
      }
    }
  }
  return metadata;
}

// Usage
const mocker = new ModuleMocker(globalThis);
let metadata = mocker.getMetadata(originalObject);
metadata = addMockImplementation(metadata!, {
  calculate: (a: number, b: number) => a * b // Override addition with multiplication
});
const mock = mocker.generateFromMetadata(metadata);

Types

interface Mock<T extends FunctionLike = UnknownFunction> extends Function, MockInstance<T> {
  new (...args: Parameters<T>): ReturnType<T>;
  (...args: Parameters<T>): ReturnType<T>;
}

interface Replaced<T = unknown> {
  restore(): void;
  replaceValue(value: T): this;
}

type Mocked<T> = T extends ClassLike
  ? MockedClass<T>
  : T extends FunctionLike
    ? MockedFunction<T>
    : T extends object
      ? MockedObject<T>
      : T;

type MockedShallow<T> = T extends ClassLike
  ? MockedClass<T>
  : T extends FunctionLike
    ? MockedFunctionShallow<T>
    : T extends object
      ? MockedObjectShallow<T>
      : T;

docs

advanced-mock-generation.md

index.md

mock-functions.md

spy-operations.md

type-system.md

tile.json