Mock HTTP Server for Testing
mock-http-server is a Node.js library designed to create controllable HTTP and HTTPS server mocks, primarily for use in functional and integration tests. It allows developers to define expected incoming requests by method and path, and then configure custom responses including status codes, headers, and body content. The current stable version is 1.4.5, with recent minor releases adding features like request history clearing, improved body parsing for various content types (text/plain, urlencoded), and specific port retrieval methods. Its release cadence appears to be feature-driven, with new functionalities and minor fixes arriving periodically. Key differentiators include its explicit control over request matching and response generation, the ability to inspect received requests for assertions, and support for both HTTP and HTTPS protocols. It aims to provide a reliable and isolated testing environment without actual network calls to external services, allowing for consistent and fast test execution.
Common errors
-
Error: listen EADDRINUSE :::9000
cause The specified port (e.g., 9000) is already in use by another process, or the mock server was not properly stopped after a previous test run.fixEnsure `server.stop()` is reliably called in your test teardown (e.g., `afterEach` or `afterAll`). If the issue persists, choose a different port, or configure the server to use port `0` which lets the OS assign an available port, then retrieve it with `server.getHttpPort()` or `server.getHttpsPort()`. -
TypeError: (0 , mock_http_server_1.ServerMock) is not a constructor
cause This error typically occurs in an ES Module context when trying to import `ServerMock` as a named export (`import { ServerMock } from 'mock-http-server';`) when the package actually provides a CommonJS default export.fixChange the import statement to a default import: `import ServerMock from 'mock-http-server';`. -
Error: connect ECONNREFUSED 127.0.0.1:9000
cause The client attempting to connect to the mock server cannot establish a connection. This usually means the mock server was not started, or it was stopped before the client could connect, or it's listening on a different host/port than expected.fixVerify that `server.start()` has completed successfully before making requests. Ensure the client is configured to connect to the correct host and port, especially if you're using dynamic port assignment (e.g., port `0`). Make sure there isn't a firewall blocking the connection. -
ReferenceError: require is not defined in ES module scope
cause You are attempting to use `require()` in a JavaScript file that is treated as an ES Module (e.g., `"type": "module"` in `package.json` or `.mjs` file extension).fixRefactor your import statements to use ESM `import ServerMock from 'mock-http-server';`. If you need to mix CommonJS `require` with ESM, you can use `import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);` but this is generally discouraged for package imports.
Warnings
- breaking The behavior of `requests()` filtering with multiple conditions changed from an 'OR' logic to an 'AND' logic in version 1.4.1. This means if you were filtering for requests matching *any* of multiple conditions, your filters will now require *all* conditions to be met, potentially causing existing tests to fail or behave unexpectedly.
- gotcha Failing to stop the server (with `server.stop()`) or clear handlers/requests (with `server.resetHandlers()` and `server.clearRequests()`) between tests can lead to port conflicts (`EADDRINUSE`) or state leakage, causing intermittent test failures. This is especially common in asynchronous test environments like `beforeEach`/`afterEach` hooks.
- gotcha The package primarily uses CommonJS `require` syntax in its examples. While it can be imported in ESM projects using `import ServerMock from 'mock-http-server';` (due to default export), attempting a named import like `import { ServerMock } from 'mock-http-server';` will fail.
- gotcha There are no official TypeScript type declarations (`.d.ts` files) bundled with `mock-http-server`. This means TypeScript users will need to create their own declaration files or use `@ts-ignore` to suppress type errors, potentially losing type safety for server configuration and request/response handling.
Install
-
npm install mock-http-server -
yarn add mock-http-server -
pnpm add mock-http-server
Imports
- ServerMock
import { ServerMock } from 'mock-http-server';import ServerMock from 'mock-http-server';
- ServerMock
const ServerMock = require('mock-http-server'); - HTTPS Configuration (fs.readFileSync)
const server = new ServerMock({ ... }, { key: require('fs').readFileSync('key.pem') });import fs from 'node:fs'; const server = new ServerMock({ host: "localhost", port: 80 }, { host: "localhost", port: 443, key: fs.readFileSync("private-key.pem"), cert: fs.readFileSync("certificate.pem") });
Quickstart
import ServerMock from 'mock-http-server';
import util from 'node:util';
describe('Test with Mock HTTP Server', function() {
// Run an HTTP server on localhost:9000
var server = new ServerMock({ host: "localhost", port: 9000 });
const startServer = util.promisify(server.start).bind(server);
const stopServer = util.promisify(server.stop).bind(server);
beforeEach(async () => {
await startServer();
});
afterEach(async () => {
server.resetHandlers(); // Clear handlers between tests
server.clearRequests(); // Clear request history
await stopServer();
});
it('should mock a GET request to /resource', async () => {
server.on({
method: 'GET',
path: '/resource',
reply: {
status: 200,
headers: { "content-type": "application/json" },
body: JSON.stringify({ message: "hello world from mock" })
}
});
// Simulate an HTTP request
const response = await fetch('http://localhost:9000/resource');
const data = await response.json();
expect(response.status).toBe(200);
expect(data).toEqual({ message: "hello world from mock" });
// Verify the request was received
const requests = server.requests({
method: 'GET',
path: '/resource'
});
expect(requests.length).toBe(1);
});
});