{"id":16128,"library":"mock-http","title":"Mock HTTP Request/Response for Node.js","description":"mock-http is a Node.js library that provides robust mock implementations of the core `http.IncomingMessage` and `http.ServerResponse` classes. This enables developers to conduct isolated unit testing of HTTP server-side logic, such as Connect, Express, or Koa middleware, without the overhead of creating a real HTTP server or managing network sockets. The library ensures full API compatibility with Node.js's native `http` module interfaces, allowing middleware to be tested in an environment closely mirroring production. Currently stable at version 1.1.1, its release cadence is generally aligned with Node.js LTS cycles for compatibility updates, rather than frequent feature additions, indicating a mature and maintenance-focused project. Its key differentiator is the faithful emulation of the standard HTTP objects, providing a reliable and predictable testing surface for complex server-side components.","status":"maintenance","version":"1.1.1","language":"javascript","source_language":"en","source_url":"github.com/commenthol/mock-http","tags":["javascript","http","mock","request","response","stream","typescript"],"install":[{"cmd":"npm install mock-http","lang":"bash","label":"npm"},{"cmd":"yarn add mock-http","lang":"bash","label":"yarn"},{"cmd":"pnpm add mock-http","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the modern way to import the mock classes in ES Modules or TypeScript. The package includes its own type definitions for `IncomingMessageMock` and `ServerResponseMock`.","wrong":"import Request from 'mock-http';","symbol":"Request, Response","correct":"import { Request, Response } from 'mock-http';"},{"note":"Imports the entire module as a namespace object, allowing access to `mock.Request` and `mock.Response`. Useful when you want to explicitly refer to the module context.","wrong":"import mock from 'mock-http';","symbol":"mock (namespace)","correct":"import * as mock from 'mock-http';"},{"note":"The standard way to import the mock classes in CommonJS Node.js environments. While the verbose `mockHttp.Request` is functionally correct, destructuring is often preferred for conciseness.","wrong":"const mockHttp = require('mock-http'); const Request = mockHttp.Request;","symbol":"Request (CJS), Response (CJS)","correct":"const { Request, Response } = require('mock-http');"}],"quickstart":{"code":"import * as mock from 'mock-http';\nimport { strict as assert } from 'assert';\n\ndescribe('mock-http example', function(){\n    // a middleware function under test\n    var middleware = function(req, res, next) {\n        var regex = /^(?:\\/test)(\\/.*|$)/;\n        req.params = '';\n\n        req.on('data', function(data){\n            req.params += data; // a simple body parser\n        });\n        req.on('end', function(){\n            if (regex.test(req.url)) {\n                req.url = req.url.replace(regex, '$1') || '/';\n                res.writeHead(200, { 'Cache-Control': 'max-age=300'});\n                res.write('this is a test');\n                res.end();\n            }\n            else {\n                next && next();\n            }\n        });\n    };\n\n    it('shall respond with a 200', function(done){\n        var req = new mock.Request({\n                    url: '/test',\n                    method: 'POST',\n                    buffer: Buffer.from('name=mock&version=first')\n                });\n        var res = new mock.Response({\n                onEnd: function() {\n                    // the test ends here\n                    assert.equal(req.url, '/');\n                    assert.equal(req.params, 'name=mock&version=first');\n                    assert.equal(res.statusCode, 200);\n                    assert.equal(res.headersSent, true);\n                    assert.equal(res.getHeader('Cache-Control'), 'max-age=300');\n                    assert.equal(res.hasEnded(), true);\n                    done();\n                }\n            });\n        middleware(req, res, function(){\n            done(new Error('Next middleware should not have been called'));\n        });\n    });\n\n    it('shall call next middleware', function(done){\n        var req = new mock.Request({\n                    url: '/other',\n                    method: 'POST',\n                    buffer: Buffer.from('data=something')\n                });\n        var res = new mock.Response({\n                onEnd: function() {\n                    done(new Error('Response should not have ended, next middleware should be called'));\n                }\n            });\n        middleware(req, res, function(){\n            // This is the expected path for this test case\n            assert.equal(res.hasEnded(), false); // Ensure response was not ended by this middleware\n            done();\n        });\n    });\n});","lang":"javascript","description":"Demonstrates mocking HTTP requests and responses to test a simple Connect-style middleware function, verifying headers, body, status, and middleware chaining behavior."},"warnings":[{"fix":"Design tests to focus on HTTP protocol-level interactions (headers, body, status codes) rather than direct socket manipulation or properties that depend on a live network connection.","message":"This library provides mock implementations of `http.IncomingMessage` and `http.ServerResponse`, meaning it does not involve actual network sockets. Functionality typically handled by the underlying socket, such as low-level `net.Socket` events or properties like `remoteAddress`, will not be accurately mimicked or may not function as expected in a real HTTP server environment.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For `mock.Response`, use the `onEnd` callback to trigger test assertions. For `mock.Request`, ensure all 'data' and 'end' event listeners have processed their input before concluding the test.","message":"When testing asynchronous middleware, particularly those that process request bodies (e.g., `req.on('data')`, `req.on('end')`), it's crucial to ensure your test harness properly waits for the middleware's asynchronous operations to complete before asserting on the mock response state. Failure to do so can lead to flaky tests or incorrect assertions.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Prefer using public methods like `res.statusCode`, `res.getHeader()`, and `res.hasEnded()` where possible. If `_internal` is necessary, be prepared for potential adjustments during major version upgrades.","message":"The library exposes an `_internal` property on `mock.Response` for querying states like `headers`, `buffer`, and `ended`. While useful for testing, relying on the exact structure of this private property directly might be fragile if future major versions change its internal representation without explicit API changes.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure you are importing the library correctly using named imports (`import { Request, Response } from 'mock-http';`) or a namespace import (`import * as mock from 'mock-http';`) and then referencing `mock.Request` or `mock.Response`.","cause":"Attempting to instantiate `Request` or `Response` from an incorrectly imported `mock` object, or the `mock` object is undefined.","error":"TypeError: mock.Request is not a constructor"},{"fix":"Verify the middleware logic correctly handles all execution paths, ensuring `res.end()` or `next()` is called under expected test conditions, especially for asynchronous operations.","cause":"The middleware being tested did not call `res.end()` or `next()`, which prevents the test's `onEnd` callback or the subsequent middleware function from executing.","error":"AssertionError: test never reaches here"},{"fix":"Review the middleware logic to prevent multiple calls to `res.end()` or any write operations to the response stream after the response has been finalized.","cause":"The middleware attempted to write to the response stream (e.g., `res.write()`) after `res.end()` had already been called, which is not allowed by the `http.ServerResponse` contract.","error":"Error: write after end"}],"ecosystem":"npm"}