Light my Request
light-my-request is a utility library designed to simulate HTTP requests against Node.js HTTP servers without requiring the server to be bound to a network port or even in a listening state. This makes it an ideal tool for writing fast, isolated tests for server logic, as well as for debugging server-side applications. The current stable version is 6.6.0. The project maintains a consistent release cadence, frequently delivering minor versions and patch updates to address features, bug fixes, and performance improvements, as evidenced by the regular 6.x releases. A core differentiator of this library is its ability to interact directly with an `http.createServer` dispatch function, effectively injecting fake request and response objects without relying on actual socket connections. It provides flexibility by supporting both traditional callback-based request handling and modern Promise-based (async/await) patterns, alongside a fluent, chainable API for constructing complex requests.
Common errors
-
TypeError: (0, light_my_request_1.inject) is not a function
cause Attempting to use CommonJS `require` syntax or an incorrect named import in an ESM module context, leading to `inject` being undefined.fixIn an ESM file (`.mjs` or `type: 'module'` in `package.json`), use `import { inject } from 'light-my-request';`. If using TypeScript, ensure correct `moduleResolution` in `tsconfig.json`. -
TypeError: Cannot read properties of undefined (reading 'payload')
cause This typically occurs when attempting to access properties like `payload` from the response object before the Promise returned by `inject` has resolved, or if the `inject` call itself failed and was not caught.fixEnsure you `await` the `inject` call when using `async/await`, or handle the `.then()` and `.catch()` branches correctly when using Promises. For example: `const res = await inject(...); console.log(res.payload);` -
Error: Cannot find module 'form-auto-content'
cause Attempting to use the `form-auto-content` package for multipart data without explicitly installing it as a dependency.fixInstall `form-auto-content` if you intend to use it for `multipart/form-data` requests: `npm install form-auto-content`.
Warnings
- gotcha light-my-request operates by directly invoking an HTTP dispatch function, not by making actual network requests. This means your Node.js HTTP server does not need to be running or listening on a port for `inject` to work. Code paths that rely on a live network socket (e.g., `server.address()`, `socket.remoteAddress`) will not function as they would in a real HTTP context.
- gotcha When using `light-my-request` in an ESM (ECMAScript Module) context, you must use named imports for functions like `inject`. Direct default `require()` patterns from CommonJS are not compatible and will result in runtime errors.
- deprecated While callback-based APIs are still supported, the library's examples and modern usage strongly encourage the adoption of Promise-based or async/await syntax for better asynchronous control flow and error handling. Callbacks may be de-emphasized in future major versions.
Install
-
npm install light-my-request -
yarn add light-my-request -
pnpm add light-my-request
Imports
- inject
const inject = require('light-my-request').injectimport { inject } from 'light-my-request' - DispatchFunc
import { DispatchFunc } from 'light-my-request'import type { DispatchFunc } from 'light-my-request' - * as LightMyRequest
import * as LightMyRequest from 'light-my-request'
Quickstart
import { inject } from 'light-my-request';
import http from 'node:http';
const dispatch = function (req, res) {
let body = '';
req.on('data', chunk => { body += chunk; });
req.on('end', () => {
if (req.method === 'POST' && req.url === '/echo') {
res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': body.length });
res.end(body);
} else if (req.url === '/') {
const reply = 'Hello World';
res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': reply.length });
res.end(reply);
} else {
res.writeHead(404);
res.end('Not Found');
}
});
};
async function runInjection() {
try {
const getResponse = await inject(dispatch).get('/').end();
console.log('GET /:', getResponse.payload); // Expected: Hello World
const postResponse = await inject(dispatch)
.post('/echo')
.payload('This is a test POST body')
.end();
console.log('POST /echo:', postResponse.payload); // Expected: This is a test POST body
} catch (err) {
console.error('Injection failed:', err);
}
}
runInjection();