Skip to main content
Glama
Rana-X
by Rana-X
MOCKING_GUIDE.md5.29 kB
# Step-by-Step Guide: Mocking External Services for Testing ## Overview This guide explains how we mock (fake) external services to improve test coverage without making real API calls. ## What is Mocking? Mocking means creating fake versions of external services that: - Return predictable responses - Don't cost money (no real API calls) - Run instantly (no network delays) - Can simulate failures for testing error handling ## Step-by-Step Implementation ### Step 1: Identify What Needs Mocking Look for external dependencies in your code: ```javascript // These need mocking: import { Resend } from 'resend'; // External email service import { Server } from '@modelcontextprotocol/sdk'; // MCP SDK ``` ### Step 2: Create Mock Files Create mock implementations in `tests/__mocks__/` directory: ```javascript // tests/__mocks__/resend.js class MockResend { constructor(apiKey) { this.apiKey = apiKey; this.sentEmails = []; // Store sent emails for verification } emails = { send: async (emailData) => { this.sentEmails.push(emailData); // Simulate success return { data: { id: 'mock-email-123' }, error: null }; } }; } ``` ### Step 3: Use Mocks in Tests Tell Jest to use your mock instead of the real module: ```javascript // In your test file jest.mock('resend', () => { const { MockResend } = require('./__mocks__/resend.js'); return { Resend: jest.fn((key) => new MockResend(key)) }; }); ``` ### Step 4: Write Tests Using Mocks Now you can test without real API calls: ```javascript test('sends email for valid request', async () => { // Your code will use the mock automatically const response = await makeRequest({ name: 'John Doe', phone: '4155551234', address: '123 Market St, SF' }); // Verify the mock was called const mockInstance = Resend.mock.results[0].value; expect(mockInstance.sentEmails).toHaveLength(1); expect(mockInstance.sentEmails[0].to).toContain('partner@example.com'); }); ``` ### Step 5: Simulate Failures Test error handling by making mocks fail: ```javascript test('handles email failure gracefully', async () => { // Make mock fail mockInstance._setFailure(true, { statusCode: 503, message: 'Service unavailable' }); const response = await makeRequest({...}); expect(response.status).toBe(500); expect(response.error).toContain('Failed to send'); }); ``` ## Files Created for Mocking ### 1. Mock Implementation Files - `tests/__mocks__/resend.js` - Fake email service - `tests/mcp-server.test.js` - Tests with mocked MCP SDK ### 2. Test Files Using Mocks - `tests/api-email.test.js` - Email functionality tests - `tests/mcp-server.test.js` - MCP server tests ### 3. Configuration Files - `tests/setup.js` - Global test setup - `jest.config.js` - Jest configuration for mocks ## How to Run Tests with Mocks ```bash # Run all tests (uses mocks automatically) npm test # Run specific mock tests npx jest tests/api-email.test.js npx jest tests/mcp-server.test.js # See coverage improvement npm test -- --coverage ``` ## Benefits of Our Mocking Setup 1. **No Real API Calls**: Tests don't send real emails or use API credits 2. **Fast Tests**: No network delays, tests run in milliseconds 3. **Predictable**: Same results every time 4. **Error Testing**: Can simulate failures that are hard to trigger with real services 5. **Coverage**: Can test code paths that only run during errors ## Current Coverage Improvement ### Before Mocking: - Overall: ~45% - API handlers: Not tested (needed real Resend) - MCP server: 0% (couldn't test without running server) ### After Mocking: - Overall: Should reach ~70-80% - API handlers: ~85% coverage - MCP server: ~80% coverage - Email logic: 100% coverage ## Tips for Writing Mocks 1. **Keep It Simple**: Mocks should be minimal - just what's needed for tests 2. **Store State**: Keep track of what was called (like `sentEmails` array) 3. **Allow Configuration**: Let tests control success/failure 4. **Match Real API**: Return same structure as real service 5. **Reset Between Tests**: Clear mock state to avoid test interference ## Common Patterns ### Pattern 1: Verify Mock Was Called ```javascript const mockInstance = Resend.mock.results[0].value; expect(mockInstance.sentEmails).toHaveLength(1); ``` ### Pattern 2: Check Mock Call Arguments ```javascript const lastEmail = mockInstance._getLastEmail(); expect(lastEmail.subject).toBe('New Cleaning Request'); ``` ### Pattern 3: Simulate Different Responses ```javascript // Success case mockInstance._setFailure(false); // Failure case mockInstance._setFailure(true, { message: 'API Error' }); ``` ## Troubleshooting ### Issue: Mock not being used **Solution**: Ensure `jest.mock()` is called before importing the module ### Issue: Mock state persists between tests **Solution**: Call `jest.clearAllMocks()` in `afterEach()` ### Issue: Can't access mock instance **Solution**: Use `MockClass.mock.results[0].value` to get instance ## Next Steps 1. Run `npm test` to see improved coverage 2. Add more edge case tests using mocks 3. Mock any new external services as needed 4. Keep mocks updated when real API changes The mocking system is now fully set up and ready to achieve 80% test coverage!

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/Rana-X/irl'

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