Skip to main content
Glama
testing-advanced.md4.01 kB
--- trigger: manual --- # Advanced Testing Guidelines This document covers advanced testing approaches for the MCP-ify project. For basic test structure and abstractions, see [testing-basics.md](testing-basics.md). ## Dependency Injection Over Mocking The project favors dependency injection with test-friendly interfaces over traditional mocking: ```typescript // ❌ Avoid: Using mocks that simulate behavior it('processes data correctly', async () => { // Setting up mocks with implementation details jest.mock('../api-client'); const mockFetch = jest.fn().mockResolvedValue({ json: () => Promise.resolve({ data: 'test-data' }), }); apiClient.fetch = mockFetch; const result = await processData('input'); expect(mockFetch).toHaveBeenCalledWith('/endpoint', { data: 'input' }); expect(result).toEqual('test-data'); }); // ✅ Better: Using dependency injection with test-friendly interfaces it('processes data correctly', async () => { // Simple test implementation of the dependency const testApiClient = { fetch: async (url: string, data: unknown) => { // Verification happens in the test implementation expect(url).toBe('/endpoint'); expect(data).toEqual({ data: 'input' }); // Return test data directly return { data: 'test-data' }; }, }; // Inject the test implementation const result = await processData('input', testApiClient); expect(result).toEqual('test-data'); }); ``` ### Key dependency injection patterns 1. **Design for testability** ```typescript // ❌ Avoid: Direct dependency on implementation async function processData(input: string) { const response = await apiClient.fetch('/endpoint', { data: input }); return response.data; } // ✅ Better: Accept dependencies as parameters async function processData(input: string, client: ApiClient = defaultApiClient) { const response = await client.fetch('/endpoint', { data: input }); return response.data; } ``` 2. **Class-based injection** ```typescript // ✅ Constructor injection for classes class DataProcessor { static create(client: ApiClient = defaultApiClient): DataProcessor { return new DataProcessor(client); } private constructor(client: ApiClient) {} async process(input: string) { const response = await this.client.fetch('/endpoint', { data: input }); return response.data; } } ``` 3. **Test-friendly interfaces** - Focus on the behavior needed for testing, not implementation details - Create simple implementations that return predetermined test data - Include validation logic in the test implementation when needed - Consider creating reusable test implementations for common dependencies ## Code Quality in Tests **Tests must adhere to the same code quality standards as production code.** This includes: 1. **Strict Type Safety** - No use of the generic `Function` type; always use specific function signatures - No `any` type usage, even in test implementations - Proper typing for all test fixtures and mock implementations - Type assertions (casting) should be avoided or carefully justified 2. **Lint Rule Compliance** - Lint errors are never acceptable in test code - No disabled lint rules without explicit justification in comments - All tests must pass the project's linting configuration - Same code style and formatting standards apply to tests and production code 3. **Clean Test Implementations** ```typescript // ❌ Avoid: Using 'any' or 'Function' types in test code const testServer = { resource: function(id: string, uri: any, callback: Function) { /* ... */ } }; // ✅ Better: Properly typed test implementations type ResourceCallback = (uri: string, args: Record<string, unknown>) => Promise<ResourceResult>; const testServer = { resource: function(id: string, uri: string, callback: ResourceCallback) { /* ... */ } }; ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wycats/mcpify'

If you have feedback or need assistance with the MCP directory API, please join our Discord server