@skielder/mockas
Version:
A simple and fast mocking api server
283 lines (232 loc) • 7.7 kB
Markdown
# Mockas - API Mocking Library

Mockas is a simple and flexible library for mocking APIs in Node.js and the browser. It allows defining routes, generating dummy data, simulating authentication, and intercepting fetch requests.
## Features
- **Fluent API**: Define routes and responses intuitively.
- **Node.js & Browser**: Works server-side (e.g., with Express) and client-side (by intercepting fetch).
- **Static & Dynamic Responses**: Return fixed data or use handler functions for dynamic logic.
- **Path Parameters**: Supports routes like `/users/:id`.
- **Delay Simulation**: Add artificial latency to responses.
- **Authentication**: Simple setup for token-based authentication (Bearer token) and login routes.
- **Data Generation**: Create dummy data (users, posts, etc.) based on schemas.
- **Automatic API Generation**: Create complete RESTful APIs for resources with just a few lines of configuration.
- **Fetch Interception**: Replace `window.fetch` in the browser to intercept requests.
- **Middleware**: Easily integrate Mockas into Express/Connect applications.
## Installation
```bash
npm install @skielder/mockas
# or
yarn add @skielder/mockas
```
## Basic Usage
### Import Mockas
```js
// Import (Node.js)
const Mockas = require('mockas');
```
### Create a Mockas Instance
```js
const mockas = new Mockas({
delay: 50, // Optional global delay of 50ms
baseUrl: '/api/v1' // Optional: Removes '/api/v1' from the path before matching
});
```
### Define Routes
```js
// Static response
mockas.get('/users')
.willReturn([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]);
// Dynamic response
mockas.get('/users/:id')
.withHandler((requestData) => {
const userId = parseInt(requestData.params.id, 10);
if (userId === 1) {
return { id: 1, name: 'Alice', email: 'alice@example.com' };
}
return { status: 404, data: { error: 'User not found' } };
});
// POST route with status and delay
mockas.post('/users')
.withStatus(201)
.withDelay(100)
.withHandler((requestData) => {
console.log('Received new user data:', requestData);
const newUser = { ...requestData, id: Date.now() };
delete newUser.query;
delete newUser.params;
return newUser;
});
```
### Use Mockas
#### Option A: Intercept global Fetch (Browser)
```js
if (typeof window !== 'undefined') {
mockas.installGlobalFetch();
fetch('/api/v1/users')
.then(res => res.json())
.then(console.log);
fetch('/api/v1/users/1')
.then(res => res.json())
.then(console.log);
// Clean up later:
// mockas.uninstallGlobalFetch();
}
```
#### Option B: Manual Requests (Node.js)
```js
async function runManualRequest() {
const response = await mockas.request('GET', '/users');
console.log('Manual request response:', response);
const notFound = await mockas.request('GET', '/users/99');
console.log('Manual not found:', notFound);
}
if (typeof window === 'undefined') {
runManualRequest();
}
```
#### Option C: As Middleware (Node.js with Express/Connect)
```js
const express = require('express');
const Mockas = require('mockas');
const app = express();
const port = 3000;
const mockas = new Mockas({
baseUrl: '/api', // Optional: prefix for mock routes
delay: 50, // Optional: Global delay
});
mockas.get('/api/hello')
.willReturn({ message: 'Hello from Mocka!' })
.register();
mockas.get('/api/users')
.willReturn([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
])
.withStatus(200)
.register();
mockas.get('/api/users/:id')
.withHandler((reqData) => {
const userId = parseInt(reqData.params.id, 10);
if (userId === 1) return { id: 1, name: 'Alice', details: 'Found user 1' };
if (userId === 2) return { id: 2, name: 'Bob', details: 'Found user 2' };
return { error: 'User not found' };
})
.register();
mockas.post('/api/echo')
.withHandler((reqData) => {
console.log('Received data in /api/echo:', reqData);
return { received: reqData };
})
.withStatus(201)
.register();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(Mockas.middleware(mockas));
app.get('/real-api/status', (req, res) => {
res.json({ status: 'Real API endpoint is active!' });
});
app.use((req, res) => {
res.status(404).json({ error: 'Not Found (Express Fallback)' });
});
app.listen(port, () => {
console.log(`Express server with Mockas running at http://localhost:${port}`);
});
```
## Core Concepts
### Defining Routes
Use the HTTP methods (`get`, `post`, `put`, `patch`, `delete`) on the Mockas instance to start defining a route:
```js
mockas.get('/path');
mockas.post('/path');
// ... etc
```
### Configuring Responses
#### Static Response
```js
mockas.get('/notfound').withStatus(404).willReturn({ error: 'Not Found' });
```
#### Dynamic Response
```js
mockas.get('/items')
.withHandler((reqData) => {
const filter = reqData.query.filter;
const items = [{ id: 1, name: 'A' }, { id: 2, name: 'B' }];
if (filter) {
return items.filter(item => item.name.includes(filter));
}
return items;
});
```
#### Response Headers
```js
mockas.get('/cached-data')
.withResponseHeaders({ 'Cache-Control': 'max-age=3600' })
.willReturn({ data: '...' });
```
#### Delay Simulation
```js
mockas.get('/slow-resource').withDelay(1500).willReturn({ done: true });
```
#### Authentication
```js
mockas.get('/admin/data').expectAuth().willReturn({ secret: 'data' });
```
#### Path Parameters
```js
mockas.get('/products/:category/:productId')
.withHandler((reqData) => {
const { category, productId } = reqData.params;
return { info: `Details for product ${productId} in category ${category}` };
});
```
#### Authentication
Mockas supports simple token-based authentication using `setupAuth`:
```js
mockas.setupAuth({
tokenKey: 'Authorization',
tokenValue: 'Bearer ',
users: [
{ id: 1, username: 'claude', password: 'password123', role: 'admin' }
],
autoCreateLoginRoute: true
});
```
To protect routes:
```js
mockas.get('/secure/resource').expectAuth().willReturn({ data: 'secret' });
```
### Generating Dummy Data
Use `createDummyData` to generate test data based on a schema:
```js
const postSchema = {
id: { type: 'increment', start: 1 },
userId: { type: 'randomInt', min: 1, max: 10 },
title: (ctx) => `Post ${ctx.currentItem.id}`,
body: { type: 'lorem', words: 30 },
tags: ['news', 'tech', 'code'],
publishedAt: { type: 'date' }
};
const posts = mockas.createDummyData(postSchema, 5);
console.log(posts);
```
### Automatic API Generation
```js
const managedUsers = mockas.createUserAPI(); // Creates /users, /users/:id etc.
const managedProfiles = mockas.createUserAPI('/profiles', [], true); // Authentication for all routes
```
### Fetch Interception (Browser)
```js
mockas.installGlobalFetch();
```
### Middleware (Node.js)
```js
app.use(Mockas.middleware(mockasInstance));
```
## License
Mockas is an open-source library released under the [MIT License](https://opensource.org/licenses/MIT).
## Reporting Issues
If you encounter any issues or bugs while using Mockas, please feel free to open an issue on our [GitHub repository](https://github.com/skielder/mockas/issues). We appreciate your feedback and contributions to improve the library!
Thank you for using Mockas!