Registry / testing / xhr-mock

xhr-mock

JSON →
library2.5.1jsnpmunverified

XHR-mock is a JavaScript utility designed for intercepting and mocking `XMLHttpRequest` objects, primarily for testing purposes or for front-end development against an unbuilt backend. It allows developers to define mock responses for specific HTTP methods and URLs, enabling reliable and isolated unit and integration tests for code that relies on browser-native `XMLHttpRequest` or libraries built upon it, such as Axios, jQuery, and Superagent. The current stable version is 2.5.1. The library is actively maintained with periodic updates and improvements, demonstrated by its progression through several minor and major versions since its initial release. A key differentiator is its ability to operate seamlessly in both Node.js environments (for server-side testing) and browser environments, while maintaining compliance with the WHATWG XHR specification. It offers a simple API for setting up global mocks and ensuring proper cleanup, which is crucial for preventing test pollution.

npm install xhr-mock
INSTALL
IMPORT
SIG · XHR-MOCK
X
xhr-mock
testingjavascriptv2.5.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

mock
import mock from 'xhr-mock';
import { mock } from 'xhr-mock';
This is the primary way to import the mocking utility in modern JavaScript environments using bundlers (ESM).
mock
const mock = require('xhr-mock');
const mock = require('xhr-mock').default;
Used for CommonJS environments, typically in Node.js or older browser tooling. `require('xhr-mock')` directly provides the default export.
XHRMock (global)
const mock = XHRMock;
import mock from 'xhr-mock';
When `xhr-mock` is loaded directly via a `<script>` tag in the browser (e.g., from a CDN), the utility is exposed globally as `XHRMock`. Importing via `import` or `require` will not work in this scenario.

This quickstart demonstrates how to set up `xhr-mock` to intercept and respond to XMLHttpRequest calls for both GET and POST requests. It includes `beforeEach` and `afterEach` hooks to ensure proper test isolation by setting up and tearing down the mock for each simulated test case.

import mock from 'xhr-mock'; // This function simulates application code that uses XMLHttpRequest. // It will use the real XMLHttpRequest unless xhr-mock intercepts it. async function fetchData(url: string, method: string = 'GET', body?: object): Promise<any> { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { try { resolve(JSON.parse(xhr.responseText)); } catch (e) { resolve(xhr.responseText); } } else { reject(new Error(`Request failed with status ${xhr.status}: ${xhr.statusText}`)); } }; xhr.onerror = () => { reject(new Error('Network error or request aborted.')); }; xhr.open(method, url); if (body) { xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(body)); } else { xhr.send(); } }); } // Simulate a basic test runner environment for demonstration const describe = (name: string, fn: () => void) => { console.log(`\nDescribe: ${name}`); fn(); }; const it = async (name: string, fn: () => Promise<void>) => { console.log(` It: ${name}`); try { await fn(); console.log(` ✅ Passed: ${name}`); } catch (e: any) { console.error(` ❌ Failed: ${name} - ${e.message}`); } }; const beforeEach = (fn: () => void) => { globalThis.beforeEachCallbacks.push(fn); }; const afterEach = (fn: () => void) => { globalThis.afterEachCallbacks.push(fn); }; const expect = (value: any) => ({ toBe: (expected: any) => { if (value !== expected) throw new Error(`Expected ${expected}, got ${value}`); }, toEqual: (expected: any) => { if (JSON.stringify(value) !== JSON.stringify(expected)) { throw new Error(`Expected deep equality ${JSON.stringify(expected)}, got ${JSON.stringify(value)}`); } } }); globalThis.beforeEachCallbacks = []; globalThis.afterEachCallbacks = []; async function runAllTests() { for (const beforeEachCb of globalThis.beforeEachCallbacks) { beforeEachCb(); } // In a real test runner, 'it' blocks would be collected and run here } describe('xhr-mock usage', () => { beforeEach(() => mock.setup()); afterEach(() => mock.teardown()); it('should mock a GET request successfully', async () => { mock.get('/api/data', (req, res) => { return res.status(200).body(JSON.stringify({ message: 'Mocked GET data' })); }); const result = await fetchData('/api/data'); expect(result).toEqual({ message: 'Mocked GET data' }); }); it('should mock a POST request with specific body', async () => { let receivedBody: object | undefined; mock.post('/api/users', (req, res) => { receivedBody = JSON.parse(req.body() || '{}'); return res.status(201).body(JSON.stringify({ id: 'user-123', ...receivedBody })); }); const userData = { name: 'Alice' }; const result = await fetchData('/api/users', 'POST', userData); expect(receivedBody).toEqual(userData); expect(result).toEqual({ id: 'user-123', name: 'Alice' }); }); it('should handle network error (mocked)', async () => { mock.get('/api/error', (req, res) => { return res.status(500).body('Internal Server Error'); }); try { await fetchData('/api/error'); throw new Error('Expected request to fail, but it succeeded.'); } catch (e: any) { expect(e.message).toBe('Request failed with status 500: Internal Server Error'); } }); }); runAllTests();
Debug
Known issues
gotchaFailing to call `mock.setup()` and `mock.teardown()` around your tests can lead to 'leaky' mocks, where mock configurations from one test interfere with subsequent tests. This results in unpredictable test failures and flakiness.
fix
Always wrap your test logic with `mock.setup()` before the test and `mock.teardown()` after the test. For most testing frameworks (Jest, Mocha, Vitest), this means using `beforeEach(() => mock.setup())` and `afterEach(() => mock.teardown())` hooks.
affects: >=0.1.0
gotchaWhen using `xhr-mock` in a Node.js environment, especially without a browser-like global environment (e.g., `jsdom`), you might encounter issues if the underlying code expects a full `XMLHttpRequest` implementation to be present before `xhr-mock` takes over. While `xhr-mock` replaces the global `XMLHttpRequest` during `setup()`, its ability to do so might depend on the initial state of the global object.
fix
Ensure your Node.js test environment is configured to provide a `jsdom`-like global `XMLHttpRequest` (e.g., by setting `testEnvironment: 'jsdom'` in Jest) or verify that `xhr-mock` correctly initializes its own stub of `XMLHttpRequest` in your specific setup. If problems persist, consider adding a polyfill like `xmlhttprequest` *before* `xhr-mock` is invoked.
affects: >=0.1.0
gotchaThere are different ways to import or access `xhr-mock` depending on your environment (bundler vs. no-bundler, ESM vs. CommonJS). Using the wrong import mechanism for your context will lead to runtime errors or `undefined` references.
fix
If using a bundler with modern JS, use `import mock from 'xhr-mock';`. For Node.js CommonJS, use `const mock = require('xhr-mock');`. If loaded directly in the browser via a script tag, use the global `XHRMock` object.
affects: >=0.1.0
Errors
Common errors & fixes
ReferenceError: XMLHttpRequest is not defined
This error typically occurs when running XMLHttpRequest-dependent code in a Node.js environment that lacks a global `XMLHttpRequest` object, and `xhr-mock.setup()` has not been called or is unable to correctly initialize its mock.
fix
Ensure your test environment (e.g., Jest) uses a browser-like environment like `jsdom` (`testEnvironment: 'jsdom'`). Also, verify that `mock.setup()` is called before any code that interacts with `XMLHttpRequest`.
Error: Mocks not cleared between tests.
This is a descriptive error or observed behavior indicating that a mock set up in one test is affecting subsequent tests, leading to inconsistent results.
fix
Implement `afterEach(() => mock.teardown());` in your test suite to ensure that all mock configurations are reset to their original state after each test runs, preventing leakage.
TypeError: Cannot read properties of undefined (reading 'body')
This usually happens when attempting to access methods like `req.body()` or `res.body()` on a request or response object that is `undefined` or has an unexpected structure within your mock handler, or when the HTTP method doesn't typically carry a body (e.g., GET requests).
fix
Carefully inspect your mock handler function (`(req, res) => { ... }`) to ensure `req` and `res` objects are properly handled and their methods are called correctly. Verify the request being mocked matches the expected method and body type. Ensure your mock response object has the correct properties.
Upgrade
Version history
2.5.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
29 hits · last 30 days
node
24
OpenAI (training)
1
Resources
xhr-mock — npm install xhr-mock · libregistry