### Setup development environment Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Commands to clone the repository and install project dependencies. ```bash git clone https://github.com/ike18t/ts-mockery.git cd ts-mockery npm install npm test ``` -------------------------------- ### Include Setup File in Karma Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Ensure the setup file is loaded before test files in the Karma configuration. ```javascript // karma.conf.js module.exports = function(config) { config.set({ frameworks: ['jasmine', 'karma-typescript'], files: [ // Setup file runs first 'lib/test-setup.ts', // Then all other files { pattern: 'lib/**/*.ts' } ], preprocessors: { 'lib/**/*.ts': ['karma-typescript'] }, // ... rest of config }); }; ``` -------------------------------- ### Initialize ts-mockery for Jest Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Create a setup file to register the Jest adapter. ```typescript import { Mock } from 'ts-mockery'; // Configure ts-mockery to use Jest Mock.configure('jest'); ``` -------------------------------- ### Install ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/README.md Install the package as a development dependency. ```bash npm install --save-dev ts-mockery ``` -------------------------------- ### Configuring Jasmine Adapter Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Setup instructions for using the Jasmine adapter with ts-mockery. ```typescript // karma.conf.js import { Mock } from 'ts-mockery'; Mock.configure('jasmine'); ``` -------------------------------- ### Mock.staticMethod Usage Examples Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Examples for mocking class static methods, module exports, and handling partial return values. ```typescript class FileUtils { static readFile(path: string): string { throw new Error('Not implemented'); } static writeFile(path: string, content: string): void { throw new Error('Not implemented'); } } Mock.staticMethod(FileUtils, 'readFile', () => 'file content'); Mock.staticMethod(FileUtils, 'writeFile', Mock.noop); expect(FileUtils.readFile('/path/to/file')).toBe('file content'); expect(FileUtils.writeFile).toHaveBeenCalledWith('/path/to/file', expect.anything()); ``` ```typescript // utils.ts export const calculateTax = (amount: number) => amount * 0.1; export const formatCurrency = (amount: number) => `$${amount.toFixed(2)}`; // In test import * as Utils from './utils'; Mock.staticMethod(Utils, 'calculateTax', () => 5.0); Mock.staticMethod(Utils, 'formatCurrency', (amount) => `€${amount}`); expect(Utils.calculateTax(100)).toBe(5.0); expect(Utils.formatCurrency).toHaveBeenCalledWith(100); ``` ```typescript class UserRepository { static getUser(id: number): { id: number; name: string; email: string } { throw new Error('Not implemented'); } } // Return only required fields Mock.staticMethod(UserRepository, 'getUser', () => ({ id: 1, name: 'John' })); const user = UserRepository.getUser(1); expect(user.id).toBe(1); expect(user.name).toBe('John'); expect(user.email).toBeUndefined(); ``` -------------------------------- ### Full Jest Configuration Example Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md A comprehensive Jest configuration file including ts-mockery requirements. ```javascript // jest.config.js module.exports = { // Test environment testEnvironment: 'node', // Files to run before tests setupFiles: ['/jest-setup.ts'], // Important for ts-mockery static method mocking restoreMocks: true, clearMocks: true, resetMocks: true, // TypeScript support preset: 'ts-jest', testMatch: ['**/__tests__/**/*.ts', '**/*.spec.ts'], // Module resolution moduleNameMapper: { '^@/(.*)$': '/src/$1' }, // Coverage collectCoverageFrom: [ 'src/**/*.ts', '!src/**/*.d.ts' ] }; ``` -------------------------------- ### Initialize ts-mockery for Jasmine Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Setup file to register Jasmine as the testing framework for ts-mockery. ```typescript import { Mock } from 'ts-mockery'; // Configure ts-mockery to use Jasmine Mock.configure('jasmine'); ``` -------------------------------- ### Configuring Jest Adapter Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Setup instructions for using the Jest adapter with ts-mockery. ```typescript // jest-setup.ts import { Mock } from 'ts-mockery'; Mock.configure('jest'); // In jest.config.js module.exports = { setupFiles: ['/jest-setup.ts'], restoreMocks: true // Important: Required for static method mocking }; ``` -------------------------------- ### Configure Jest for ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Initialize the mock configuration in a setup file and update the Jest configuration to include the setup file and enable mock restoration. ```typescript import { Mock } from 'ts-mockery'; Mock.configure('jest'); ``` ```javascript module.exports = { setupFiles: ['/jest-setup.ts'], restoreMocks: true // Important: Required for static method mocking }; ``` -------------------------------- ### Quick Start with ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Demonstrates creating a type-safe mock for a service interface and using it within a test. ```typescript import { Mock } from 'ts-mockery'; interface UserService { getUser(id: number): Promise<{ id: number; name: string; email: string }>; updateUser(user: { id: number; name: string }): void; } // Create a type-safe mock const userServiceMock = Mock.of({ getUser: () => Promise.resolve({ id: 1, name: 'John' }), // email is optional updateUser: Mock.noop // Auto-spied function }); // Use in tests const result = await userServiceMock.getUser(1); expect(result.id).toBe(1); expect(userServiceMock.updateUser).toHaveBeenCalled(); ``` -------------------------------- ### Configure ts-mockery for Jasmine Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Call this in your karma setup file to initialize the Jasmine adapter. ```typescript Mock.configure('jasmine') ``` -------------------------------- ### Configure ts-mockery globally Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Initialize the framework once in a global test setup file to avoid redundant configuration. ```typescript // jest-setup.ts or karma-test-shim.ts import { Mock } from 'ts-mockery'; // Single configuration for all tests Mock.configure('jest'); // or 'jasmine' ``` -------------------------------- ### Mock.noop Usage Examples Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Demonstrates using Mock.noop for void methods and mixed interface implementations. ```typescript interface EventHandler { onClick: () => void; onSubmit: (data: any) => void; onError: (error: Error) => void; } const handlerMock = Mock.of({ onClick: Mock.noop, onSubmit: Mock.noop, onError: Mock.noop }); handlerMock.onClick(); expect(handlerMock.onClick).toHaveBeenCalled(); ``` ```typescript interface Service { loadData(): Promise; cleanup(): void; process(data: string): string; } const serviceMock = Mock.of({ loadData: () => Promise.resolve({ data: 'test' }), cleanup: Mock.noop, process: (data) => data.toUpperCase() }); ``` -------------------------------- ### Custom SpyAdapter Implementation Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Example of implementing the SpyAdapter interface for a hypothetical testing framework and registering it via Mock.configure(). ```typescript import { SpyAdapter } from 'ts-mockery'; class CustomFrameworkAdapter implements SpyAdapter { getSpy(property: string): any { // Use your framework's spy creation API return yourFramework.createSpy(property); } spyAndCallFake( object: T, key: K, stub: T[K] & (() => unknown) ): void { // Replace the property with a wrapper that tracks calls const originalValue = object[key]; let callCount = 0; const args: any[] = []; object[key] = ((...callArgs: any[]) => { callCount++; args.push(callArgs); return stub(...callArgs); }) as any; // Store metadata for assertions (object[key] as any).__spy = { callCount, callArgs: args, calls: { reset: () => { callCount = 0; args.length = 0; } } }; } spyAndCallThrough(object: T, key: K): void { if (typeof object[key] === 'function') { const original = object[key]; let callCount = 0; const args: any[] = []; object[key] = ((...callArgs: any[]) => { callCount++; args.push(callArgs); return (original as any)(...callArgs); }) as any; (object[key] as any).__spy = { callCount, callArgs: args, calls: { reset: () => { callCount = 0; args.length = 0; } } }; } } } // Use the custom adapter Mock.configure(new CustomFrameworkAdapter()); ``` -------------------------------- ### Mock.from Usage Examples Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Demonstrates creating mocks for circular references and complex class inheritance structures. ```typescript import { of } from 'rxjs'; interface ReactiveService { data$: Observable; process(): void; } // Mock.of might throw RangeError with circular references const mock = Mock.from({ data$: of(1, 2, 3), process: Mock.noop }); ``` ```typescript class BaseService { protected baseMethod(): void {} } interface ExtendedService extends BaseService { extendedMethod(): string; } const mock = Mock.from(new BaseService()); ``` -------------------------------- ### Configure Jest for ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Update Jest configuration to include the setup file and enable mock restoration. ```javascript module.exports = { // ... other Jest options setupFiles: ['/jest-setup.ts'], restoreMocks: true // IMPORTANT: Required for static method mocking }; ``` ```typescript import type { Config } from 'jest'; const config: Config = { // ... other Jest options setupFiles: ['/jest-setup.ts'], restoreMocks: true // IMPORTANT: Required for static method mocking }; export default config; ``` -------------------------------- ### Mocking Map-like Objects Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Example of using Mock.all to create a mock for a dictionary-style object. ```typescript type MapLike = { [key: string]: unknown }; const mockedData = Mock.all(); const x = jest.fn(); x.mockResolvedValue(mockedData); const result = await x(); expect(result).toBe(mockedData); ``` -------------------------------- ### Project File Structure Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/README.md Displays the directory layout of the project workspace. ```text /workspace/home/output/ ├── README.md ← This file ├── INDEX.md ← Quick navigation guide ├── types.md ← Type definitions ├── configuration.md ← Setup guide ├── errors.md ← Error reference ├── advanced-patterns.md ← Real-world patterns └── api-reference/ ├── mock-class.md ← Mock API docs └── spy-adapter.md ← SpyAdapter docs ``` -------------------------------- ### Configure Jasmine for ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Set up the Jasmine framework within Karma and initialize the mock configuration. ```javascript // karma.conf.js module.exports = function(config) { config.set({ frameworks: ['jasmine', 'karma-typescript'], files: ['**/*.spec.ts'], preprocessors: { '**/*.ts': ['karma-typescript'] }, // Add configuration setup client: { jasmine: { // Jasmine config } } }); }; // In test setup or beforeEach import { Mock } from 'ts-mockery'; Mock.configure('jasmine'); ``` -------------------------------- ### Triggering Circular Reference Errors Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Examples of direct and indirect circular references that trigger the RangeError in Mock.of(). ```typescript // Direct circular reference type Circular = { [key: string]: Circular }; const myObject: Circular = {}; myObject.foo = myObject; // Self-reference Mock.of(myObject); // Throws error // Indirect circular reference through nested properties interface Node { value: string; child?: Node; } const node: Node = { value: 'root' }; const child: Node = { value: 'child', child: node }; // References parent node.child = child; Mock.of(node); // May throw error ``` -------------------------------- ### Mock.configure() Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/INDEX.md Configures the spy framework adapter. ```APIDOC ## Mock.configure() ### Description Sets the spy framework adapter (e.g., 'jest' or 'jasmine') used by ts-mockery. ### Signature `configure(adapter: string | SpyAdapter) => void` ### Parameters - **adapter** (string | SpyAdapter) - Required - The adapter name or implementation. ``` -------------------------------- ### Mock Static Methods in Jest Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Example of using static method mocking within a Jest test suite. ```typescript // src/services/user.service.spec.ts import { Mock } from 'ts-mockery'; import { UserService } from './user.service'; import * as UserRepository from './user.repository'; describe('UserService', () => { beforeEach(() => { // Note: Mock.configure('jest') is already called in jest-setup.ts // No need to call it again in tests }); it('creates a user', () => { Mock.staticMethod(UserRepository, 'save', () => Promise.resolve({ id: 1, name: 'John' }) ); const service = new UserService(); expect(UserRepository.save).toHaveBeenCalled(); }); }); ``` -------------------------------- ### Configure Jest for ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/INDEX.md Set up the mock configuration and Jest integration. ```typescript import { Mock } from 'ts-mockery'; Mock.configure('jest'); ``` ```javascript module.exports = { setupFiles: ['/jest-setup.ts'], restoreMocks: true }; ``` -------------------------------- ### Invalid RecursivePartial Assignments Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/types.md Examples of type errors that occur when assigning incorrect types or unknown properties to a RecursivePartial. ```typescript // ❌ Wrong type for property const invalid1: RecursivePartial = { id: 'wrong' }; // ❌ Unknown property const invalid2: RecursivePartial = { unknown: 'field' }; // ❌ Nested type mismatch interface Service { config: { host: string; port: number }; } const invalid3: RecursivePartial = { config: { host: 123 } // port would be optional, but host must be string }; ``` -------------------------------- ### Mock Static Methods in Jasmine Tests Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Example of using ts-mockery to mock static methods within a Jasmine test suite. ```typescript // lib/services/user.service.spec.ts import { Mock } from 'ts-mockery'; import { UserService } from './user.service'; import * as UserRepository from './user.repository'; describe('UserService', () => { beforeEach(() => { // Note: Mock.configure('jasmine') is already called in test-setup.ts // No need to call it again }); it('creates a user', () => { Mock.staticMethod(UserRepository, 'save', () => Promise.resolve({ id: 1, name: 'John' }) ); const service = new UserService(); expect(UserRepository.save).toHaveBeenCalled(); }); }); ``` -------------------------------- ### Create a mock object with ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/README.md Demonstrates the basic syntax for creating a mock implementation of a TypeScript interface. ```typescript // Inline examples show real usage interface Service { getData(): Promise; } const mock = Mock.of({ getData: () => Promise.resolve({ id: 1 }) }); ``` -------------------------------- ### Configure ts-mockery for Jest Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Call this in your jest-setup.ts file to initialize the Jest adapter. ```typescript Mock.configure('jest') ``` -------------------------------- ### Mock.of Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Creates a mock object of type T with optional property and method stubs applied. It supports automatic spy setup for functions and handles nested objects, arrays, and promises. ```APIDOC ## Mock.of(stubs?: RecursivePartial): T ### Description Creates a mock object of type T with optional property and method stubs. Missing properties remain undefined, and functions are automatically set up as spies. ### Parameters - **stubs** (RecursivePartial) - Optional - Object containing property and method implementations. ### Return Type - **T** - A mock object of type T with all provided stubs applied. ### Throws - **Error** - Thrown when a stubbed property has a circular reference. ``` -------------------------------- ### Basic Mock Creation Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Creates a mock object with defined methods and property stubs, utilizing Mock.noop for void functions. ```typescript interface UserService { getUser(id: number): Promise<{ id: number; name: string; email: string }>; deleteUser(id: number): void; } const userServiceMock = Mock.of({ getUser: (id) => Promise.resolve({ id, name: 'John' }), // email is optional deleteUser: Mock.noop }); await userServiceMock.getUser(1); expect(userServiceMock.getUser).toHaveBeenCalledWith(1); ``` -------------------------------- ### Mocking Static Methods Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Demonstrates how to mock static methods of a class using Mock.staticMethod. ```typescript class FileUtils { static readFile(path: string): string { // Implementation } static writeFile(path: string, content: string): void { // Implementation } } // Mock static methods Mock.staticMethod(FileUtils, 'readFile', () => 'mocked content'); Mock.staticMethod(FileUtils, 'writeFile', Mock.noop); // Use in tests const content = FileUtils.readFile('/path/to/file'); expect(content).toBe('mocked content'); ``` -------------------------------- ### Configure Jest for ts-mockery Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Initialize the mock framework and ensure proper Jest configuration for static method support. ```typescript // jest-setup.ts import { Mock } from 'ts-mockery'; Mock.configure('jest'); // Add to jest.config.js module.exports = { setupFiles: ['/jest-setup.ts'], restoreMocks: true // Important for static method mocking }; ``` -------------------------------- ### Mock.configure(framework) Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Configures the global testing environment adapter used by ts-mockery. ```APIDOC ## Mock.configure(framework) ### Description Sets the testing framework adapter to be used for creating spies. This should be called during test setup. ### Parameters - **framework** ('jest' | 'jasmine') - Required - The testing framework environment to configure. ### Usage Example ```typescript import { Mock } from 'ts-mockery'; Mock.configure('jest'); ``` ``` -------------------------------- ### Execute test suites Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Commands to run specific test runners or the full test suite. ```bash npm run test:jest # Run Jest tests npm run test:jasmine # Run Jasmine tests npm test # Run all tests ``` -------------------------------- ### getSpy Framework Implementations Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Framework-specific implementations for creating a spy. ```typescript getSpy() { return jest.fn(); } ``` ```typescript getSpy(property: string) { return jasmine.createSpy(property); } ``` -------------------------------- ### Configure framework-specific adapters Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Select the appropriate adapter based on the test runner being used. ```typescript // ✅ Jest projects Mock.configure('jest'); // ✅ Jasmine/Karma projects Mock.configure('jasmine'); // ✅ Vitest projects (with custom adapter) Mock.configure(new VitestAdapter()); ``` -------------------------------- ### Implement Vitest Adapter Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md A concrete implementation of the SpyAdapter interface specifically for the Vitest framework. ```typescript import { SpyAdapter } from 'ts-mockery'; import { vi } from 'vitest'; class VitestAdapter implements SpyAdapter { getSpy(property: string): any { return vi.fn(); } spyAndCallFake( object: T, key: K, stub: T[K] & (() => unknown) ): void { vi.spyOn(object as any, key as any).mockImplementation(stub); (object[key] as any).mockClear(); } spyAndCallThrough(object: T, key: K): void { if (typeof object[key] === 'function') { vi.spyOn(object as any, key as any); } } } // Use in vitest setup import { Mock } from 'ts-mockery'; Mock.configure(new VitestAdapter()); ``` -------------------------------- ### Mock.configure(adapter) Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Configures the spy framework adapter used by ts-mockery. ```APIDOC ## Mock.configure(adapter) ### Description Configures the spy framework adapter used by ts-mockery. ### Signature `public static configure(spyAdapter: 'jest' | 'jasmine' | SpyAdapter): void;` ### Parameters - **spyAdapter** ('jest' | 'jasmine' | SpyAdapter) - Required - Either a built-in framework name ('jest' or 'jasmine') or a custom SpyAdapter implementation. ``` -------------------------------- ### Create and Use a Basic Mock Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/README.md Define a mock for a TypeScript interface and use it within test expectations. ```typescript import { Mock } from 'ts-mockery'; interface UserService { getUser(id: number): Promise<{ id: number; name: string }>; deleteUser(id: number): void; } // Create a mock const mock = Mock.of({ getUser: () => Promise.resolve({ id: 1, name: 'John' }), deleteUser: Mock.noop }); // Use in tests expect(mock.getUser(1)).toBeTruthy(); expect(mock.deleteUser).toHaveBeenCalled(); ``` -------------------------------- ### Fluent API pattern usage Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/types.md Basic syntax for extending a mock object. ```typescript Mock.extend(mockObject).with({ newProperty: value }); ``` -------------------------------- ### Create environment-based configuration mocks in TypeScript Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/advanced-patterns.md Uses a factory function to return typed configuration objects based on the provided environment string. Requires the Config interface to be defined beforehand. ```typescript interface Config { env: 'dev' | 'prod' | 'test'; apiUrl: string; features: { enableNewUI: boolean; enableBeta: boolean; }; } function createConfigMock(environment: 'dev' | 'prod' | 'test'): Config { const configs = { dev: { env: 'dev' as const, apiUrl: 'http://localhost:3000', features: { enableNewUI: true, enableBeta: true } }, prod: { env: 'prod' as const, apiUrl: 'https://api.example.com', features: { enableNewUI: false, enableBeta: false } }, test: { env: 'test' as const, apiUrl: 'http://test-api.example.com', features: { enableNewUI: true, enableBeta: false } } }; return Mock.of(configs[environment]); } describe('Environment configs', () => { it('uses dev config', () => { const config = createConfigMock('dev'); expect(config.apiUrl).toBe('http://localhost:3000'); expect(config.features.enableBeta).toBe(true); }); it('uses prod config', () => { const config = createConfigMock('prod'); expect(config.apiUrl).toBe('https://api.example.com'); expect(config.features.enableNewUI).toBe(false); }); }); ``` -------------------------------- ### Mock Full Service Integration Stack Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/advanced-patterns.md Shows how to coordinate multiple service mocks to test integrated business logic flows. ```typescript interface Logger { info(message: string): void; error(message: string): void; } interface Database { query(sql: string): Promise; execute(sql: string, params: any[]): Promise; } interface EmailService { send(to: string, subject: string, body: string): Promise; } interface UserManagementService { logger: Logger; database: Database; emailService: EmailService; createUser(email: string, name: string): Promise; } // Create coordinated mocks for integration testing const logger = Mock.of({ info: Mock.noop, error: Mock.noop }); const database = Mock.of({ query: () => Promise.resolve([]), execute: Mock.noop }); const emailService = Mock.of({ send: Mock.noop }); const userService = Mock.of({ logger, database, emailService, createUser: async (email, name) => { logger.info(`Creating user ${name}`); await database.execute('INSERT INTO users VALUES (?)', [name]); await emailService.send(email, 'Welcome', 'Welcome to our service'); } }); // Test the integrated behavior describe('User creation flow', () => { it('logs and sends email on user creation', async () => { await userService.createUser('john@example.com', 'John'); expect(logger.info).toHaveBeenCalledWith('Creating user John'); expect(database.execute).toHaveBeenCalled(); expect(emailService.send).toHaveBeenCalledWith( 'john@example.com', 'Welcome', 'Welcome to our service' ); }); }); ``` -------------------------------- ### Mocking Generic Repository Interfaces Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/types.md Shows how to use Mock.of to implement a generic repository interface. ```typescript interface Repository { find(id: string): Promise; save(entity: T): Promise; delete(id: string): Promise; } interface User { id: string; name: string; email: string; } const userRepo = Mock.of>({ find: () => Promise.resolve({ id: '1', name: 'John' }), save: Mock.noop, delete: () => Promise.resolve(true) }); ``` -------------------------------- ### Implement Defensive Mock Creation Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Safely initialize mocks by attempting creation with Mock.of and falling back to Mock.from within a try-catch block. ```typescript import { Mock } from 'ts-mockery'; interface ComplexService { data$: Observable; process(): void; } // Attempt to create mock safely let serviceMock: ComplexService; try { serviceMock = Mock.of({ data$: of(1, 2, 3), process: Mock.noop }); } catch { // Fall back to Mock.from if circular reference detected serviceMock = Mock.from({ data$: of(1, 2, 3), process: Mock.noop }); } expect(serviceMock.process).toBeDefined(); ``` -------------------------------- ### SpyAdapterFactory.get(framework) Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Retrieves a specific spy adapter instance. ```APIDOC ## SpyAdapterFactory.get(framework) ### Description Retrieves an instance of a SpyAdapter for the specified framework. ### Parameters - **framework** ('jasmine' | 'jest' | 'noop') - Required - The framework adapter to retrieve. ### Usage Example ```typescript import { SpyAdapterFactory } from 'ts-mockery'; const jestAdapter = SpyAdapterFactory.get('jest'); ``` ``` -------------------------------- ### Implement a Custom Spy Adapter Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Define a custom adapter by implementing the SpyAdapter interface and passing it to the configuration method. ```typescript import { Mock, SpyAdapter } from 'ts-mockery'; const customAdapter: SpyAdapter = { getSpy: (property: string) => /* custom spy implementation */, spyAndCallFake: (object, key, stub) => /* custom spy setup */, spyAndCallThrough: (object, key) => /* custom spy setup */ }; Mock.configure(customAdapter); ``` -------------------------------- ### Retrieve Adapters via Factory Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Manually instantiate specific adapters using the SpyAdapterFactory. ```typescript import { SpyAdapterFactory } from 'ts-mockery'; const jestAdapter = SpyAdapterFactory.get('jest'); const jasmineAdapter = SpyAdapterFactory.get('jasmine'); const noopAdapter = SpyAdapterFactory.get('noop'); ``` -------------------------------- ### Configure Spy Adapters Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Set the testing framework environment to ensure the correct spy implementation is used. ```typescript // jest-setup.ts import { Mock } from 'ts-mockery'; Mock.configure('jest'); // karma.conf.js import { Mock } from 'ts-mockery'; Mock.configure('jasmine'); ``` -------------------------------- ### Project Directory Structure Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/INDEX.md Visual representation of the library's source code organization and configuration files. ```text ts-mockery/ ├── lib/ │ ├── mockery.ts # Core Mock class and types │ ├── spy-adapter-factory.ts # Factory for adapter creation │ ├── spy-adapters/ │ │ ├── spy-adapter.ts # SpyAdapter interface │ │ ├── jest-adapter.ts # Jest implementation │ │ ├── jasmine-adapter.ts # Jasmine implementation │ │ └── noop-adapter.ts # No-op adapter │ ├── mockery.spec.ts # Comprehensive test suite │ ├── recursive-partial.spec.ts # Type system tests │ └── test/ │ └── importFixture.ts # Test fixtures ├── index.ts # Public API exports ├── jest-setup.ts # Jest configuration example ├── karma-test-shim.ts # Karma configuration example ├── jest.config.ts # Jest config ├── karma.conf.js # Karma config ├── tsconfig.json # TypeScript configuration ├── package.json # Package metadata └── README.md # User documentation ``` -------------------------------- ### Configure Spy Framework Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Initialize the spy framework before running tests to ensure assertions like toHaveBeenCalled() function correctly. ```typescript // Ensure Mock.configure is called before any tests import { Mock } from 'ts-mockery'; Mock.configure('jest'); // or 'jasmine' ``` -------------------------------- ### Mocking Imported Modules Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Shows how to mock specific functions exported from modules. ```typescript // utils.ts export const calculateTax = (amount: number) => amount * 0.1; export const formatCurrency = (amount: number) => `$${amount.toFixed(2)}`; // In your test file import * as Utils from './utils'; import { Mock } from 'ts-mockery'; // Mock specific functions from imported modules Mock.staticMethod(Utils, 'calculateTax', () => 5.0); Mock.staticMethod(Utils, 'formatCurrency', (amount) => `€${amount}`); // Use in tests const tax = Utils.calculateTax(100); const formatted = Utils.formatCurrency(50); expect(tax).toBe(5.0); expect(formatted).toBe('€50'); expect(Utils.calculateTax).toHaveBeenCalledWith(100); ``` -------------------------------- ### Mock.all() Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/INDEX.md Creates a proxy mock of type T. ```APIDOC ## Mock.all() ### Description Creates a proxy-based mock for type T. ### Signature `all() => T` ``` -------------------------------- ### Create a basic mock Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/INDEX.md Use Mock.of to create a mock object for a given interface. Mock.noop can be used for void methods. ```typescript import { Mock } from 'ts-mockery'; interface UserService { getUser(id: number): Promise; deleteUser(id: number): void; } const mock = Mock.of({ getUser: () => Promise.resolve({ id: 1, name: 'John' }), deleteUser: Mock.noop }); expect(mock.deleteUser).toHaveBeenCalled(); ``` -------------------------------- ### Handle mixed test runner environments Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Configure the framework within specific test suites when multiple runners are present in the same project. ```typescript // Rare case: mixing Jest and Jasmine describe('Jest Tests', () => { beforeAll(() => { Mock.configure('jest'); }); // ... tests }); describe('Jasmine Tests', () => { beforeAll(() => { Mock.configure('jasmine'); }); // ... tests }); ``` -------------------------------- ### Mock.configure Signature Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md The static method signature for configuring the spy framework adapter. ```typescript public static configure(spyAdapter: 'jest' | 'jasmine' | SpyAdapter): void; ``` -------------------------------- ### Configure ts-mockery for Vitest Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Requires a custom Vitest adapter implementation passed to the configuration method. ```typescript Mock.configure() ``` -------------------------------- ### Configure Spy Adapter Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md The internal implementation of the Mock.configure method. ```typescript public static configure(spyAdapter: 'jest' | 'jasmine' | SpyAdapter): void { this.spyAdapter = typeof spyAdapter === 'string' ? SpyAdapterFactory.get(spyAdapter) : spyAdapter; } ``` -------------------------------- ### Configure ts-mockery for Custom Frameworks Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Use a custom SpyAdapter implementation for frameworks not natively supported. ```typescript Mock.configure(customAdapter) ``` -------------------------------- ### spyAndCallThrough Framework Implementations Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Framework-specific implementations for enabling call-through behavior on a spy. ```typescript spyAndCallThrough(object: T, key: K) { if (typeof object[key] === typeof Function) { jest.spyOn(object as any, key as any); } } ``` ```typescript spyAndCallThrough(object: T, key: K) { const value = object[key]; if (typeof value === typeof Function && !(jasmine as any).isSpy(value)) { spyOn(object, key).and.callThrough(); } } ``` -------------------------------- ### spyAndCallFake(object: T, key: K, stub: Function): void Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Creates a spy on an object property and configures it to execute a provided stub implementation. ```APIDOC ## spyAndCallFake(object: T, key: K, stub: Function): void ### Description Creates a spy on an object property and configures it to execute the provided stub implementation instead of the original. It clears existing call history and tracks all new calls. ### Signature `spyAndCallFake(object: T, key: K, stub: T[K] & (() => unknown)): void;` ### Parameters - **object** (T) - Required - The object containing the property to spy on. - **key** (K) - Required - The property name to spy on. - **stub** (Function) - Required - The function implementation to execute when the spied property is called. ``` -------------------------------- ### Extending Mock.all with Implementations Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Shows how to combine lazy spy generation with specific method implementations using Mock.extend. ```typescript interface LargeService { fetch(url: string): Promise; parse(data: string): object; validate(obj: object): boolean; } const mock = Mock.all(); // Add specific implementations to some methods Mock.extend(mock).with({ fetch: () => Promise.resolve({ id: 1 }), parse: (data) => JSON.parse(data) }); // Other methods remain as spies const valid = mock.validate({}); expect(mock.validate).toHaveBeenCalled(); ``` -------------------------------- ### Basic Mocking Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Create a partial mock by specifying only the required properties. ```typescript interface ApiClient { baseUrl: string; timeout: number; request(path: string): Promise; } // Create a partial mock - only specify what you need const apiMock = Mock.of({ baseUrl: 'https://api.example.com', request: () => Promise.resolve({ data: 'test' }) }); // timeout is automatically undefined (optional) ``` -------------------------------- ### Configure Test Framework Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/README.md Configure the library to work with specific test runners. ```typescript // jest-setup.ts import { Mock } from 'ts-mockery'; Mock.configure('jest'); ``` ```typescript // karma-test-shim.ts or Karma setup import { Mock } from 'ts-mockery'; Mock.configure('jasmine'); ``` -------------------------------- ### Partial Object Mocking Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Demonstrates creating a mock where only a subset of properties are defined, leaving others undefined. ```typescript interface ApiClient { baseUrl: string; timeout: number; request(path: string): Promise; } const apiMock = Mock.of({ baseUrl: 'https://api.example.com', request: () => Promise.resolve({ data: 'test' }) // timeout is automatically undefined }); expect(apiMock.baseUrl).toBe('https://api.example.com'); ``` -------------------------------- ### spyAndCallFake Framework Implementations Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md Framework-specific implementations for configuring a spy to call a fake implementation. ```typescript spyAndCallFake( object: T, key: K, stub: T[K] & (() => unknown) ) { jest.spyOn(object as any, key as any).mockImplementation(stub); (object[key] as jest.Mock).mockClear(); } ``` ```typescript spyAndCallFake( object: T, key: K, stub: T[K] & (() => unknown) ) { const value = object[key]; const spy = ( (jasmine as any).isSpy(value) ? value : spyOn(object, key) ) as jasmine.Spy; spy.calls.reset(); spy.and.callFake(stub); } ``` -------------------------------- ### Mock concurrent service operations with Promises Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/advanced-patterns.md Demonstrates mocking asynchronous service methods using Promise.resolve to simulate concurrent data fetching. Useful for testing components that utilize Promise.all. ```typescript interface ConcurrentService { fetchUser(id: string): Promise; fetchPosts(userId: string): Promise; fetchComments(postId: string): Promise; } describe('Concurrent operations', () => { it('handles multiple concurrent requests', async () => { const service = Mock.of({ fetchUser: () => Promise.resolve({ id: '1', name: 'John' }), fetchPosts: () => Promise.resolve([ { id: '1', title: 'Post 1', userId: '1' }, { id: '2', title: 'Post 2', userId: '1' } ]), fetchComments: () => Promise.resolve([ { id: '1', text: 'Comment 1', postId: '1' } ]) }); const [user, posts, comments] = await Promise.all([ service.fetchUser('1'), service.fetchPosts('1'), service.fetchComments('1') ]); expect(user.name).toBe('John'); expect(posts).toHaveLength(2); expect(comments).toHaveLength(1); }); }); ``` -------------------------------- ### Implement Custom SpyAdapter Interface Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Define a custom adapter class by implementing the SpyAdapter interface to bridge ts-mockery with a specific test framework. ```typescript import { SpyAdapter } from 'ts-mockery'; class CustomTestFrameworkAdapter implements SpyAdapter { getSpy(property: string): any { // Return a spy function using your framework's API return yourFramework.createSpy(property); } spyAndCallFake( object: T, key: K, stub: T[K] & (() => unknown) ): void { // Setup spy that calls the stub object[key] = stub as any; // Add spy tracking... } spyAndCallThrough(object: T, key: K): void { // Setup spy that calls through to original const original = object[key]; object[key] = ((...args: any[]) => { // Track call... return (original as any)(...args); }) as any; } } ``` -------------------------------- ### Mock.from Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Creates a mock for complex objects, handling inheritance and circular references. ```APIDOC ## Mock.from(source) ### Description Creates a mock instance for complex types, specifically designed to handle class inheritance hierarchies and objects containing circular references safely. ``` -------------------------------- ### NoopAdapter Implementation Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/spy-adapter.md A no-operation adapter that returns undefined or performs no action, serving as the default when no framework is configured. ```typescript // All methods are no-ops const noop: SpyAdapter = { getSpy() { return undefined; }, spyAndCallFake() { return; }, spyAndCallThrough() { return; } }; ``` -------------------------------- ### Using Mock.from() Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md The primary solution for mocking objects that contain circular references. ```typescript import { Mock } from 'ts-mockery'; import { of } from 'rxjs'; interface Service { data$: Observable; process(): void; } // Use Mock.from for objects with circular references const mock = Mock.from({ data$: of(1, 2, 3), process: () => console.log('processing') }); expect(mock.data$).toBeDefined(); ``` -------------------------------- ### Create a lazy proxy mock Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/INDEX.md Use Mock.all to create a proxy that mocks all methods of an interface automatically. ```typescript interface LargeService { method1(): string; method2(): number; // ... hundreds of methods } const mock = Mock.all(); mock.method1(); expect(mock.method1).toHaveBeenCalled(); ``` -------------------------------- ### Handling Linked Lists or Tree Structures Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Shows the transition from Mock.of to Mock.from for data structures with parent-child relationships. ```typescript interface TreeNode { value: number; parent?: TreeNode; children?: TreeNode[]; } const parent: TreeNode = { value: 1 }; const child: TreeNode = { value: 2, parent: parent }; parent.children = [child]; // ❌ May throw error Mock.of(parent); // ✅ Use Mock.from instead Mock.from(parent); ``` -------------------------------- ### Mock.all() Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Creates a proxy-based mock object that automatically generates spies on-demand for any accessed property or method. ```APIDOC ## Mock.all() ### Description Creates a proxy-based mock object that automatically generates spies on-demand for any accessed property or method. ### Signature `public static all(): T;` ### Returns - **T** - A proxy object of type T with lazy spy generation. ``` -------------------------------- ### Mock.all Signature Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md The static method signature for creating a proxy-based mock object. ```typescript public static all(): T; ``` -------------------------------- ### Mocking Conditional Generic API Clients Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/advanced-patterns.md Shows how to mock API clients that utilize generic response wrappers. Useful for testing services that handle varying data structures within a consistent envelope. ```typescript interface ApiResponse { data: T; metadata: { timestamp: number; version: string; }; } interface ApiClient { get(url: string): Promise>; post(url: string, body: T): Promise>; } const client = Mock.of>({ get: () => Promise.resolve({ data: { id: '1', name: 'John' }, metadata: { timestamp: Date.now(), version: '1.0' } }), post: (url, body) => Promise.resolve({ data: body, metadata: { timestamp: Date.now(), version: '1.0' } }) }); ``` -------------------------------- ### Configure Karma for Jasmine Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/configuration.md Standard Karma configuration for projects using Jasmine and karma-typescript. ```javascript module.exports = function(config) { config.set({ // Frameworks frameworks: ['jasmine', 'karma-typescript'], // Files files: [ { pattern: 'lib/**/*.ts' }, { pattern: 'lib/**/*.spec.ts' } ], // Preprocessors preprocessors: { 'lib/**/*.ts': ['karma-typescript'] }, // Reporters reporters: ['progress', 'kjhtml'], // Browser browsers: ['Chrome'], // Jasmine configuration jasmine: { random: false, seed: null, stopSpecOnExpectationFailure: false } }); }; ``` -------------------------------- ### Promise Support Source: https://github.com/ike18t/ts-mockery/blob/master/README.md Mock services returning promises with partial resolved values. ```typescript interface ApiService { fetchUser(id: number): Promise<{ id: number; name: string; email: string; profile: { avatar: string }; }>; updateUser(data: { name: string; }): Promise<{ success: boolean; message: string }>; deleteUser(id: number): Promise; } const apiMock = Mock.of({ // Promise resolved values support partial objects fetchUser: () => Promise.resolve({ id: 1, name: 'John' // email and profile are optional due to RecursivePartial }), // Return minimal required data updateUser: () => Promise.resolve({ success: true }), // Void promises work seamlessly deleteUser: () => Promise.resolve() }); ``` -------------------------------- ### Mock.from Method Signature Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/api-reference/mock-class.md Defines the signature for creating a mock from an existing object. ```typescript public static from(object: RecursivePartial): T; ``` -------------------------------- ### Builder Pattern for Mock Creation in TypeScript Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/advanced-patterns.md Encapsulate complex mock configuration logic within a builder class to improve test readability and maintainability. ```typescript class UserRepositoryMockBuilder { private defaults: RecursivePartial = { getUser: () => Promise.resolve({ id: 1, name: 'John', email: 'john@example.com', isAdmin: false }), getAdmin: () => Promise.resolve({ id: 1, name: 'Admin', email: 'admin@example.com', isAdmin: true }), getByEmail: () => Promise.resolve({ id: 1, name: 'John', email: 'john@example.com', isAdmin: false }) }; withAdmin(): this { this.defaults.getUser = () => Promise.resolve({ id: 1, name: 'Admin User', isAdmin: true }); return this; } withGetUserReturning(user: Partial): this { this.defaults.getUser = () => Promise.resolve({ id: 1, name: 'John', email: 'john@example.com', ...user }); return this; } build(): UserRepository { return Mock.of(this.defaults); } } // Usage const mock = new UserRepositoryMockBuilder() .withAdmin() .withGetUserReturning({ name: 'Jane' }) .build(); ``` -------------------------------- ### Handling Complex Object Graphs Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Demonstrates using Mock.from for complex graphs that create cycles through multiple levels. ```typescript interface Graph { nodes: Array<{ id: string; neighbors: Graph['nodes']; }>; } const node1 = { id: '1', neighbors: [] }; const node2 = { id: '2', neighbors: [node1] }; node1.neighbors = [node2]; // Creates cycle // ❌ Throws error Mock.of({ nodes: [node1, node2] }); // ✅ Use Mock.from Mock.from({ nodes: [node1, node2] }); ``` -------------------------------- ### Handling RxJS Observables Source: https://github.com/ike18t/ts-mockery/blob/master/_autodocs/errors.md Demonstrates using Mock.from to avoid circular reference errors when mocking RxJS Observables. ```typescript import { of } from 'rxjs'; interface ReactiveService { data$: Observable; } // ❌ Throws RangeError -> wrapped as Error const mock = Mock.of({ data$: of(1, 2, 3) }); // ✅ Works correctly with Mock.from const mock = Mock.from({ data$: of(1, 2, 3) }); ```