Implementing a Mock Server with Jest for API Testing
Testing applications that rely on external APIs can be challenging. A mock server allows you to simulate API responses locally, isolating your application's logic and enabling faster, more reliable testing. This challenge asks you to implement a simple mock server using Jest that can respond to specific HTTP requests with predefined data.
Problem Description
You need to create a Jest mock server that intercepts HTTP requests and returns mock responses. The server should be configurable with a set of request-response mappings. Each mapping defines a URL and an HTTP method (GET, POST, PUT, DELETE) that, when matched, triggers a specific response. The mock server should handle different HTTP methods and return appropriate status codes.
Key Requirements:
- Request Matching: The mock server must accurately match incoming requests based on URL and HTTP method.
- Response Handling: When a request matches a defined mapping, the server should return the corresponding mock response (including status code, headers, and body).
- Default Response: If no matching mapping is found, the server should return a 404 Not Found response.
- Configuration: The server should be configurable with a list of request-response mappings.
- Jest Integration: The mock server should be designed to be easily integrated into Jest tests.
Expected Behavior:
The mock server should intercept requests made during Jest tests and return the configured mock responses. It should not make actual network calls to external APIs.
Edge Cases to Consider:
- Case Sensitivity: Consider whether URL matching should be case-sensitive. (For this challenge, assume case-sensitive matching.)
- URL Matching: How should the server handle partial URL matches? (For this challenge, assume exact URL matching.)
- Multiple Matches: What should happen if multiple mappings match a request? (For this challenge, the first matching mapping should be used.)
- Headers: The mock server should be able to return mock responses with custom headers.
Examples
Example 1:
Input:
Mappings:
[
{ url: '/api/users/1', method: 'GET', status: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 1, name: 'John Doe' }) },
{ url: '/api/products', method: 'GET', status: 200, body: JSON.stringify([{ id: 1, name: 'Product 1' }]) }
]
Request: GET /api/users/1
Output:
Status Code: 200
Headers: { 'Content-Type': 'application/json' }
Body: '{"id":1,"name":"John Doe"}'
Explanation: The request matches the first mapping, so the corresponding status code, headers, and body are returned.
Example 2:
Input:
Mappings:
[
{ url: '/api/users', method: 'POST', status: 201, body: JSON.stringify({ message: 'User created' }) }
]
Request: POST /api/users
Output:
Status Code: 201
Headers: {}
Body: '{"message":"User created"}'
Explanation: The request matches the POST mapping for /api/users, returning the specified status and body.
Example 3:
Input:
Mappings:
[
{ url: '/api/data', method: 'GET', status: 200, body: 'OK' }
]
Request: GET /api/unknown
Output:
Status Code: 404
Headers: {}
Body: ''
Explanation: No mapping matches the request /api/unknown, so the default 404 response is returned.
Constraints
- The mock server should be implemented in TypeScript.
- The server should be lightweight and efficient, minimizing overhead during tests.
- The mappings should be provided as an array of objects, as shown in the examples.
- The body of the response should be a string.
- The server should only handle GET, POST, PUT, and DELETE requests. Other methods should result in a 404.
Notes
- Consider using Jest's
mockandspyOnfunctions to intercept and mock HTTP requests. - You don't need to implement a full-fledged HTTP server. The focus is on creating a mock that can be used within Jest tests.
- Think about how to make the server configurable and reusable across different test suites.
- Error handling is not a primary concern for this challenge; focus on the core request-response matching logic.
- The server should be designed to be easily testable itself. Consider writing unit tests for the mock server's functionality.