Parrot Middleware for Express
parrot-middleware is an Express.js middleware designed for mocking HTTP requests in development and testing environments. It allows developers to define a collection of 'scenarios', each comprising a list of request-response pairs. Based on the active scenario, the middleware intercepts matching incoming requests and serves the predefined mock responses. It provides dedicated control routes (`/parrot/scenario` for setting/getting the active scenario, and `/parrot/scenarios` for inspecting all available scenarios) to manage its behavior dynamically. Currently at stable version 5.3.0, the package sees active maintenance with frequent patch and minor releases, ensuring compatibility and addressing issues. Its key differentiator is the scenario-driven approach, making it easy to simulate complex backend states or error conditions without modifying frontend code or spinning up a full backend.
Common errors
-
Error: Can't set headers after they are sent to the client.
cause This typically occurs in Express when a response is attempted to be sent multiple times, often due to improper `next()` calls or asynchronous operations resolving after a response has already been sent.fixReview your middleware chain and scenario response logic. Ensure that once a mock response is served, no subsequent middleware attempts to send another response. Also, verify `next()` is called correctly if `parrot-middleware` doesn't handle a request. -
TypeError: parrot is not a function
cause This error usually indicates that the `parrot` export was not correctly imported, most commonly by attempting a CommonJS `require` call on an ESM default export or vice versa, or a named import instead of a default.fixIf using Node.js modules (ESM), use `import parrot from 'parrot-middleware';`. If strictly CommonJS, ensure your `package.json` does not have `"type": "module"` and use `const parrot = require('parrot-middleware');`. -
No scenario named '...' found
cause The scenario name provided in the POST request to `/parrot/scenario` does not exactly match any of the keys in your `scenarios` object.fixDouble-check the scenario name for typos, case sensitivity, and ensure it corresponds precisely to a key in your `scenarios.js` (or equivalent) definition.
Warnings
- breaking Version 5.0.0 was a major release, but the changelog provided does not detail specific breaking changes for `parrot-middleware`. Users upgrading from v4.x should review the `parrot` core package changes or test thoroughly for potential API alterations in middleware options or scenario processing, particularly regarding configuration structures or default behaviors.
- gotcha The `parrot-middleware` must be placed before any other routes it is intended to intercept. If another route handler matches a path before `parrot` processes it, the mock will not be served.
- gotcha To allow the `/parrot/scenario` POST endpoint to receive and parse JSON payloads for setting the active scenario, `express.json()` middleware (or an alternative body parser) must be enabled *before* `parrot-middleware`.
- gotcha When defining scenarios, ensure that your `request` objects specify the `method` if you intend to mock non-GET requests. By default, requests are matched with `GET` if no method is specified in the scenario.
Install
-
npm install parrot-middleware -
yarn add parrot-middleware -
pnpm add parrot-middleware
Imports
- parrot
const parrot = require('parrot-middleware');import parrot from 'parrot-middleware';
- scenarios
const scenarios = require('./scenarios.js');import scenarios from './scenarios.js';
- ParrotMiddlewareOptions
import { ParrotMiddlewareOptions } from 'parrot-middleware';
Quickstart
import express from 'express';
import parrot from 'parrot-middleware';
// scenarios.js
const scenarios = {
'has one ship': [
{
request: '/ship_log',
response: {
body: [{ name: 'The Jolly Roger', captain: 'Captain Hook' }],
},
},
],
'has more ships': [
{
request: '/ship_log',
response: {
body: [
{ name: 'The Jolly Roger', captain: 'Captain Hook' },
{ name: 'The Black Pearl', captain: 'Jack Sparrow' },
],
},
},
],
};
const app = express();
app.use(express.json()); // Required for parsing JSON bodies for scenario POST requests
app.use(parrot(scenarios));
app.get('/', (req, res) => res.send('Hello from main app!'));
app.listen(3001, () => {
console.log('Server running on http://localhost:3001');
console.log('Try: POST http://localhost:3001/parrot/scenario with { "scenario": "has one ship" }');
console.log('Then: GET http://localhost:3001/ship_log');
});