Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 137 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,149 @@
# Mockserver

A simple node.js based web and mail mockserver
[![npm version](https://badge.fury.io/js/@smartive%2Fmockserver.svg)](https://www.npmjs.com/package/@smartive/mockserver)
[![Docker Pulls](https://img.shields.io/docker/pulls/smartive/mockserver)](https://hub.docker.com/r/smartive/mockserver)

## Setup
Mock server with **API recording and replay** for E2E testing. Works as a proxy that can record real API responses and replay them deterministically.

## What makes it special?

- **Record & Replay**: Record real API calls, replay them in tests
- **Proxy mode**: Routes requests like `http://localhost:1080/api.example.com/path` → `https://api.example.com/path`
- **SMTP server**: Built-in mail server for email testing
- **HTTP API**: Configure mocks, recordings, and inspect requests via REST endpoints

## Quick Start

```bash
docker run -p 1080:1080 -p 25:25 smartive/mockserver
```

Or with npm:

```bash
npx @smartive/mockserver
```

## Usage

### Record & Replay

**1. Configure your app** to use the mockserver as proxy:

```bash
# .env.test
API_BASE_URL="http://localhost:1080/api.example.com"
```
npm i
npm start

**2. Record** real API responses:

```javascript
await fetch('http://localhost:1080/mock/recordings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ active: true }),
});

// Run your app - all API calls are proxied and recorded
```

## Usage with Docker Compose
**3. Export** recordings:

```javascript
const recordings = await fetch('http://localhost:1080/mock/recordings').then((r) => r.json());
writeFileSync('recordings.json', JSON.stringify(recordings));
```
version: "3.3"
services:
image: smartive/mockserver
environment:
MOCK_PATH: /mock
MOCK_HOST: 0.0.0.0
MOCK_HTTP_PORT: 1080

**4. Replay** in tests:

```javascript
import recordings from './recordings.json';

await fetch('http://localhost:1080/mock/recordings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
active: false,
recordings,
}),
});

// All requests now use recorded responses
```

### Manual Mocking

```javascript
await fetch('http://localhost:1080/mock/mock', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
request: {
match: '/api.example.com/users/.*', // Regex
},
response: {
status: 200,
body: { id: '123', name: 'Test User' },
},
}),
});
```

### Email Testing

```javascript
// Wait for next email
const email = await fetch('http://localhost:1080/mock/mails/next').then((r) => r.text());
expect(email).toContain('Welcome');
```

## API Endpoints

| Endpoint | Method | Description |
| ------------------------- | ------ | ------------------------------------ |
| `/mock/recordings` | POST | Configure recording/replay mode |
| `/mock/recordings` | GET | Get all recordings |
| `/mock/recordings/rehash` | POST | Recalculate recording hashes |
| `/mock/mock` | POST | Register a mock route |
| `/mock/routes` | GET | List all mock routes |
| `/mock/calls` | GET | Get all captured requests |
| `/mock/calls/next` | GET | Wait for next request (long-polling) |
| `/mock/mails` | GET | Get all captured emails |
| `/mock/mails/next` | GET | Wait for next email (long-polling) |
| `/mock/reset` | POST | Reset all state |
| `/mock/reset/calls` | POST | Reset calls and emails |

## Configuration

| Variable | Default | Description |
| ----------------- | --------- | ------------- |
| `MOCK_HTTP_PORT` | `1080` | HTTP port |
| `MOCK_HTTPS_PORT` | - | HTTPS port |
| `MOCK_SMTP_PORT` | `25` | SMTP port |
| `MOCK_HOST` | `0.0.0.0` | Host |
| `MOCK_PATH` | `/mock` | API base path |

## Advanced Recording Options

```javascript
await fetch('http://localhost:1080/mock/recordings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
active: true,
deleteBodyAttributesForHash: ['timestamp'], // Ignore these fields in hash
deleteHeadersForHash: ['authorization'], // Ignore these headers in hash
forwardHeadersForRoute: [
{
route: '/api.example.com',
headers: { 'X-API-Key': 'secret' },
},
],
failedRequestsResponse: { error: 'Not found' }, // Fallback response
}),
});
```

## HTTPS
## License

Set a `MOCK_HTTPS_PORT` env variable to start an https server as well.
ISC
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.