node-mocks-http, request and response doubles for Express, Koa and Next.js
Mock 'http' objects for testing Express,js, Next.js and Koa routing functions
At a glance
- What is it?
- eugef/node-mocks-http builds fake Node http request and response objects so a route handler can be called directly in a unit test without starting a server, with typed generics for Express, Koa and both the Next.js pages router and the newer app router. It is a dev dependency, MIT licensed, and the mocks carry assertion helpers like _getJSONData and _isEndCalled.
- Who is it for?
- Adopt node-mocks-http if your unit tests call route handlers directly and you want the request and response doubles to carry the Express, Koa or Next.js shape rather than hand-rolled stubs. Skip it if your tests are already end to end through a running application, since a mock only helps at the unit level.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What problem it solves
node-mocks-http provides mock http objects for testing Express, Next.js and Koa routing functions, and the README notes it could be used for any Node.js web server application that has code requiring mockups of the request and response objects.
The problem is specific. A route handler written as a function taking a request and a response is easy to test in principle, but the request and response objects are rich, framework-specific and easy to get subtly wrong in a hand-written stub. A stub that sets res.status but not res.json leaves your handler calling a method that does not exist, and the test fails for a reason unrelated to your logic. The mock gives you an object that has the whole surface.
The usage example shows the shape. Given an Express route:
app.get('/user/:id', routeHandler);and a handler function, you create a request and a response and call the handler directly:
const request = httpMocks.createRequest({
method: 'GET',
url: '/user/42',
params: {
id: 42
}
});
const response = httpMocks.createResponse();
routeHandler(request, response);No server is started and no port is bound. The test is a function call, which is the fastest possible unit test, and the failure messages point at your handler rather than at HTTP plumbing.
The response object records what happened, and the accessors whose names begin with a low line are what make assertions readable. The example reads the parsed body with response._getJSONData(), which the README describes as short-hand for JSON.parse(response._getData()), then checks the status code and three state flags: _isEndCalled(), _isJSON() and _isUTF8().
Those three flags are the useful part. They answer questions the status code cannot. Whether the handler actually called end rather than just setting a status, whether the content type was JSON, and whether the charset was set. A handler that forgets to call res.end() passes a naive test and hangs in production, so having the mock assert it is a genuine safety net.
The leading low line on these method names is a deliberate signal that they are test helpers rather than part of the response interface.
The request options and the response API
The createRequest options table is the reference for what you can set, and the defaults are worth scanning because they tell you what you get for free.
method defaults to GET and url to an empty string. originalUrl defaults to the url, and baseUrl also defaults to the url, which is a small convenience when your handler reads baseUrl. path defaults to an empty string.
Then there are the collections: params defaults to an empty object, session to undefined, cookies to an empty object, socket to an empty object, signedCookies to undefined, headers to an empty object, body to an empty object, query to an empty object and files to an empty object.
The request object returned also supports the Express request functions, which the README links to the Express documentation for. That means a handler that calls req.get, req.ip or req.protocol works without you having to stub each one.
For the response, the README documents the createResponse options and the events API, and the notable additions are the mock response event support and the ability to inspect what was written. The mock response also exposes a _getData() for the raw body, which is what you use when the handler wrote a string rather than an object.
There is also a createMocks method, which the typings section mentions alongside createRequest and createResponse. That is the convenience for the common case where you need both objects for one call.
One thing to be aware of is what a mock is not. It is not a test server, and it does not exercise middleware, routing or the actual HTTP stack. It tests the function you pass it. That is exactly what you want for unit tests and exactly what you do not want if you are trying to verify that a route is registered correctly.
TypeScript typings and the framework variants
The typings are bundled with the project, and the README explains that the createRequest, createResponse and createMocks methods are typed and generic. Unless specified explicitly, they return an Express-based request and response object.
The generic parameter is where the framework support shows. The expected type parameter expects any type that extends the NodeJS http.IncomingRequest interface or the Fetch API Request class, which means you can also mock requests coming from other frameworks.
For Next.js the pages router example is:
const mockExpressRequest = httpMocks.createRequest<NextApiRequest>({
method: 'GET',
url: '/user/42',
params: {
id: 42
}
});
const mockExpressResponse = httpMocks.createResponse<NextApiResponse>();And the newer App Router is covered too, using NextRequest and NextResponse:
const mockExpressRequest = httpMocks.createRequest<NextRequest>({
method: 'GET',
url: '/user/42',
params: {
id: 42
}
});
const mockExpressResponse = httpMocks.createResponse<NextResponse>();That distinction matters more than it looks. The pages router handlers take a NextApiRequest with a query object and a body you read directly, while the App Router handlers take a NextRequest, whose body is a stream you have to await. A mock typed for the wrong one produces a handler that type-checks in the test and fails at runtime, or the other way round. Having both cases documented means the mock can be shaped the way the real handler expects.
Koa is named in the description as supported, and the Koa context is a different object again, so the Koa case is the one to check in the API documentation rather than assume it follows the Express pattern.
The install instructions call out the TypeScript case explicitly, with npm install @types/node @types/express --save-dev, since the mock's own types reference those.
Events, the response API and what the mock does not do
Two additions to the response object are worth knowing about because they are not obvious from the name.
The mock response has event support. A handler that emits an event, or code that listens for one on the response, can be observed in a test the same way it would be in production, and that matters for handlers that stream or that report progress.
And the response records what was written, so you can inspect the body, the status code and the headers rather than inferring them. The createResponse options mirror the createRequest ones for the parts that make sense on a response, and the returned object supports the Express response functions.
What the mock does not do is worth being precise about, because it is the boundary of the whole approach.
It is not a server. Nothing binds a port, no middleware runs and the router is not consulted. If your handler depends on middleware having set something on the request, the mock does not model that.
It is not the real framework object. The mock implements the Express surface as a JavaScript object with the right methods, but a framework that changes its internals can still differ. The README's own framing that it could be used for any Node.js web server application that requires mockups of request and response objects is the honest scope: it is a well populated double, not the real thing.
It does not model streaming responses in any depth. A handler that pipes a stream to res is a case where the mock and the real response diverge, and it is worth checking the library's behaviour there before you rely on it.
And it does not cover the environment. A handler that reads process.env, calls a database or depends on a clock is not mocked by this package at all, and those dependencies need their own doubles. The mock covers the boundary between your handler and the HTTP layer, which is a useful but narrow slice.
Practically, the pattern that works is to keep handlers thin enough that the request and response are the only things they touch, and then the mock tests nearly all of the logic. When a handler reaches past the HTTP boundary, the test moves up a level.
Where this fits against the alternatives
The first alternative is supertest, which is the standard way to test an Express application end to end. The difference in approach is the level at which the test runs. Supertest starts the app, sends a real HTTP request through the router and the middleware stack, and asserts on the response. node-mocks-http calls your handler function with objects. Supertest catches wiring mistakes, middleware ordering problems and header handling that a mock never sees. A mock catches logic errors faster and gives you access to the internals of the response object, including the flags for whether end was called.
The second alternative is writing your own stubs, which is what most projects did before this package. The cost is that you end up maintaining a fake request and a fake response that grow as your handler uses more of the framework, and that they drift from what Express actually does.
The third alternative is a library that mocks the whole framework, such as a full Express testing helper or a fixture-based approach. Those are heavier, and the trade is that the framework under test stops being the real framework.
The honest limitation of the mock approach is that it can only test what your handler does with the request and response you hand it. If your handler reads something from the environment, calls out to a service, or depends on middleware having run, the mock does not model that and you need a different test for it.
That is why the sensible pattern is to use both. Unit tests with the mock for the handler logic, and a smaller number of supertest tests for the routes that actually need to be proven wired up correctly.
On maintenance, the repository is not archived, the last push was on 2026-10-18, and the releases are v1.17.2 in May 2025, v1.18.0 in July 2026 and v1.18.1 days later. The licence field on the repository reports it as a custom licence GitHub cannot classify, so read the LICENSE file before shipping it inside a commercial product.
Editorial conclusion
Adopt node-mocks-http if your unit tests call route handlers directly and you want the request and response doubles to carry the Express, Koa or Next.js shape rather than hand-rolled stubs. Skip it if your tests are already end to end through a running application, since a mock only helps at the unit level. Verify first by calling createRequest and createResponse in a test, running the handler, and asserting on the recorded data with _getJSONData and the status code, then confirm the typed generics accept the framework type you actually use.
Frequently asked questions
What does node-mocks-http provide?
Mock http request and response objects for testing Express, Next.js and Koa routing functions. You create them with createRequest, createResponse and createMocks, call the route handler directly, and inspect what was written using helpers such as _getData, _getJSONData and the _isEndCalled, _isJSON and _isUTF8 flags.
How do I install node-mocks-http?
With npm install node-mocks-http --save-dev, or yarn add node-mocks-http --dev. When using TypeScript you also need the Node and Express type packages, installed with npm install @types/node @types/express --save-dev.
Can node-mocks-http mock Next.js app router requests?
Yes. The generic type parameter accepts types extending the NodeJS http.IncomingRequest interface or the Fetch API Request class, and the README shows separate examples for NextApiRequest with the pages router and NextRequest with the app router, along with the matching response types.
What options can I set when creating a mock request?
method defaulting to GET, url, originalUrl, baseUrl, path, params, session, cookies, socket, signedCookies, headers, body, query and files, each with its own default. The returned request also supports the Express request functions.
How does node-mocks-http compare with supertest?
Supertest starts the application and sends a real HTTP request through the router and middleware, while node-mocks-http calls the handler function directly with objects. The mock is faster and lets you inspect the response internals, but it cannot catch wiring or middleware problems, so the two are usually used together.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/eugef-node-mocks-http)Was this useful?