Comprehensive mock function library providing sophisticated mocking, spying, and property replacement capabilities for JavaScript and TypeScript testing
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive TypeScript utilities for type-safe mocking with generic preservation and utility functions for working with mocked objects.
Provides type assertion for objects that have been mocked, enabling full type safety in test code.
/**
* Type assertion utility for mocked objects
* @param source - Object to assert as mocked
* @param options - Mocking depth options
* @returns Type-asserted mocked object
*/
function mocked<T extends object>(source: T, options?: {shallow: false}): Mocked<T>;
function mocked<T extends object>(source: T, options: {shallow: true}): MockedShallow<T>;
function mocked<T extends object>(source: T, _options?: {shallow: boolean}): Mocked<T> | MockedShallow<T>;Usage Examples:
import { mocked, spyOn } from "jest-mock";
class UserService {
async getUser(id: string) { return { id, name: 'User' }; }
async saveUser(user: any) { return user; }
}
const userService = new UserService();
// Spy on methods
spyOn(userService, 'getUser');
spyOn(userService, 'saveUser');
// Type assertion for full type safety
const mockedUserService = mocked(userService);
mockedUserService.getUser.mockResolvedValue({ id: '1', name: 'Test User' });
mockedUserService.saveUser.mockResolvedValue({ id: '2', name: 'Saved User' });
// Now TypeScript knows these are mock functions
console.log(mockedUserService.getUser.mock.calls); // Type-safe accessType definitions that transform regular types into their mocked equivalents while preserving the original type structure.
/**
* Deep mocked type that recursively mocks all properties
*/
type Mocked<T> = T extends ClassLike
? MockedClass<T>
: T extends FunctionLike
? MockedFunction<T>
: T extends object
? MockedObject<T>
: T;
/**
* Shallow mocked type that only mocks top-level properties
*/
type MockedShallow<T> = T extends ClassLike
? MockedClass<T>
: T extends FunctionLike
? MockedFunctionShallow<T>
: T extends object
? MockedObjectShallow<T>
: T;
/**
* Mocked class type preserving constructor signature
*/
type MockedClass<T extends ClassLike> = MockInstance<
(...args: ConstructorParameters<T>) => Mocked<InstanceType<T>>
> & MockedObject<T>;
/**
* Mocked function type preserving function signature
*/
type MockedFunction<T extends FunctionLike> = MockInstance<T> & MockedObject<T>;
/**
* Deep mocked object type
*/
type MockedObject<T extends object> = {
[K in keyof T]: T[K] extends ClassLike
? MockedClass<T[K]>
: T[K] extends FunctionLike
? MockedFunction<T[K]>
: T[K] extends object
? MockedObject<T[K]>
: T[K];
} & T;
/**
* Shallow mocked object type
*/
type MockedObjectShallow<T extends object> = {
[K in keyof T]: T[K] extends ClassLike
? MockedClass<T[K]>
: T[K] extends FunctionLike
? MockedFunctionShallow<T[K]>
: T[K];
} & T;
type MockedFunctionShallow<T extends FunctionLike> = MockInstance<T> & T;
type ClassLike = new (...args: any) => any;
type FunctionLike = (...args: any) => any;Usage Examples:
import { MockedFunction, MockedClass, Mocked } from "jest-mock";
// Function mocking
type MyFunction = (x: number) => string;
type MockedMyFunction = MockedFunction<MyFunction>;
// MockedMyFunction has both MockInstance methods and original function properties
// Class mocking
class ApiClient {
baseUrl: string;
constructor(baseUrl: string) { this.baseUrl = baseUrl; }
async get(path: string) { return {}; }
}
type MockedApiClient = MockedClass<typeof ApiClient>;
// MockedApiClient constructor returns Mocked<ApiClient> instance
// Object mocking
interface Config {
database: {
host: string;
connect(): Promise<void>;
};
cache: {
set(key: string, value: any): void;
get(key: string): any;
};
}
type MockedConfig = Mocked<Config>;
// All nested functions become MockedFunction<T>
// All nested objects become MockedObject<T>Helper types for categorizing object properties by their characteristics.
/**
* Keys that are constructors (class-like functions)
*/
type ConstructorLikeKeys<T> = keyof {
[K in keyof T as Required<T>[K] extends ClassLike ? K : never]: T[K];
};
/**
* Keys that are methods (function-like properties)
*/
type MethodLikeKeys<T> = keyof {
[K in keyof T as Required<T>[K] extends FunctionLike ? K : never]: T[K];
};
/**
* Keys that are properties (non-method, non-constructor)
*/
type PropertyLikeKeys<T> = Exclude<keyof T, ConstructorLikeKeys<T> | MethodLikeKeys<T>>;Usage Examples:
interface MyObject {
name: string; // PropertyLikeKeys
count: number; // PropertyLikeKeys
method(): void; // MethodLikeKeys
Constructor: new () => any; // ConstructorLikeKeys
}
type Methods = MethodLikeKeys<MyObject>; // 'method'
type Properties = PropertyLikeKeys<MyObject>; // 'name' | 'count'
type Ctors = ConstructorLikeKeys<MyObject>; // 'Constructor'Specialized types for spy operations that preserve original signatures while adding mock capabilities.
/**
* Generic spied type
*/
type Spied<T extends ClassLike | FunctionLike> = T extends ClassLike
? SpiedClass<T>
: T extends FunctionLike
? SpiedFunction<T>
: never;
/**
* Spied class constructor
*/
type SpiedClass<T extends ClassLike = UnknownClass> = MockInstance<
(...args: ConstructorParameters<T>) => InstanceType<T>
>;
/**
* Spied function
*/
type SpiedFunction<T extends FunctionLike = UnknownFunction> = MockInstance<
(...args: Parameters<T>) => ReturnType<T>
>;
/**
* Spied property getter
*/
type SpiedGetter<T> = MockInstance<() => T>;
/**
* Spied property setter
*/
type SpiedSetter<T> = MockInstance<(arg: T) => void>;
type UnknownFunction = (...args: Array<unknown>) => unknown;
type UnknownClass = new (...args: Array<unknown>) => unknown;Usage Examples:
import { spyOn, SpiedFunction, SpiedClass } from "jest-mock";
function myFunction(x: number): string { return x.toString(); }
class MyClass { constructor(public value: string) {} }
// Spied function maintains original signature
const spiedFn: SpiedFunction<typeof myFunction> = spyOn(obj, 'myFunction');
spiedFn.mockReturnValue('mocked');
// Spied class constructor
const SpiedConstructor: SpiedClass<typeof MyClass> = spyOn(MyClass.prototype, 'constructor');import { Mocked, MockedShallow } from "jest-mock";
// Deep mocking - all nested properties become mocked
interface NestedService {
database: {
users: {
find(id: string): Promise<User>;
save(user: User): Promise<void>;
};
posts: {
findByUser(userId: string): Promise<Post[]>;
};
};
}
type DeepMocked = Mocked<NestedService>;
// database.users.find becomes MockedFunction
// database.posts.findByUser becomes MockedFunction
// Shallow mocking - only top-level properties mocked
type ShallowMocked = MockedShallow<NestedService>;
// database property is mocked, but database.users.find is notimport { MockedFunction } from "jest-mock";
// Generic functions maintain their generic nature when mocked
function genericFunction<T>(input: T): Promise<T[]> {
return Promise.resolve([input]);
}
type MockedGeneric = MockedFunction<typeof genericFunction>;
// Still maintains <T>(input: T) => Promise<T[]> signature
// Plus MockInstance methods for control// Utility type to check if something is mockable
type IsMockable<T> = T extends ClassLike | FunctionLike ? true : false;
type CanMockString = IsMockable<string>; // false
type CanMockFunction = IsMockable<() => void>; // true
type CanMockClass = IsMockable<new () => any>; // trueinterface MockInstance<T extends FunctionLike = UnknownFunction> extends Disposable {
_isMockFunction: true;
_protoImpl: Function;
mock: MockFunctionState<T>;
getMockImplementation(): T | undefined;
getMockName(): string;
mockClear(): this;
mockReset(): this;
mockRestore(): void;
mockImplementation(fn: T): this;
mockImplementationOnce(fn: T): this;
withImplementation(fn: T, callback: () => Promise<unknown>): Promise<void>;
withImplementation(fn: T, callback: () => void): void;
mockName(name: string): this;
mockReturnThis(): this;
mockReturnValue(value: ReturnType<T>): this;
mockReturnValueOnce(value: ReturnType<T>): this;
mockResolvedValue(value: ResolveType<T>): this;
mockResolvedValueOnce(value: ResolveType<T>): this;
mockRejectedValue(value: RejectType<T>): this;
mockRejectedValueOnce(value: RejectType<T>): this;
}