Use this file to discover all available pages before exploring further.
Testing code that makes HTTP requests usually requires either running a real server or intercepting requests at the network level. Undici’s built-in mocking utilities let you intercept calls and return deterministic responses without any network activity, keeping your tests fast, isolated, and reproducible. The MockAgent class is the entry point — it wraps a real Agent and routes matching requests to configured interceptors instead.
import { MockAgent, setGlobalDispatcher } from 'undici'const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent)
Once set as the global dispatcher, all request() and fetch() calls will be handled by the mock agent. Requests that don’t match any interceptor will fall through to the real network by default — use disableNetConnect() to prevent that.
Use mockAgent.get(origin) to get a MockPool (or MockClient) for a specific origin, then call .intercept() to define what to match and .reply() to specify the response.
Basic mocked request
import { MockAgent, setGlobalDispatcher, request } from 'undici'const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent)const mockPool = mockAgent.get('http://localhost:3000')mockPool.intercept({ path: '/foo' }).reply(200, 'foo')const { statusCode, body } = await request('http://localhost:3000/foo')console.log('response received', statusCode) // response received 200for await (const data of body) { console.log('data', data.toString('utf8')) // data foo}
Call mockAgent.disableNetConnect() to ensure that any request not matched by an interceptor throws a MockNotMatchedError instead of silently hitting the network:
Disabling real network connections
import { MockAgent, request } from 'undici'const mockAgent = new MockAgent()mockAgent.disableNetConnect()// This would throw MockNotMatchedError because no interceptor matchesawait request('http://example.com')
To allow some hosts through while blocking others, use enableNetConnect() with a matcher:
Selectively allowing real requests
import { MockAgent, setGlobalDispatcher, request } from 'undici'const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent)mockAgent.enableNetConnect('example-1.com') // string: exact hostmockAgent.enableNetConnect(/\.internal\.example\.com$/) // RegExpawait request('http://example-1.com') // real requestawait request('http://blocked.com') // throws
At the end of a test, verify that every interceptor you set up was actually triggered:
Asserting no pending interceptors
import { MockAgent } from 'undici'const agent = new MockAgent()agent.disableNetConnect()agent .get('https://example.com') .intercept({ method: 'GET', path: '/' }) .reply(200)// Run your code under test here...// Throws if any interceptors were never invokedagent.assertNoPendingInterceptors()
The error message includes a formatted table showing every pending interceptor with its method, origin, path, status code, and invocation count.
By default mockAgent.get(origin) returns a MockPool (multiple connections). Pass { connections: 1 } to the MockAgent constructor to get a MockClient instead — useful when you need to test connection-specific behavior.
SnapshotAgent extends MockAgent with automatic snapshot recording. In record mode it makes real requests and saves the responses; in playback mode it replays those saved responses without touching the network.
Recording snapshots
import { SnapshotAgent, setGlobalDispatcher } from 'undici'const agent = new SnapshotAgent({ mode: 'record', snapshotPath: './test/snapshots/api-calls.json'})setGlobalDispatcher(agent)// Makes real HTTP requests and records themconst response = await fetch('https://api.example.com/users')const users = await response.json()await agent.saveSnapshots()
Replaying snapshots
import { SnapshotAgent, setGlobalDispatcher } from 'undici'const agent = new SnapshotAgent({ mode: 'playback', snapshotPath: './test/snapshots/api-calls.json'})setGlobalDispatcher(agent)// Returns the previously recorded response — no real request madeconst response = await fetch('https://api.example.com/users')
Snapshot files can contain sensitive data such as authorization tokens. Always add them to .gitignore when recording against real APIs, and use the excludeHeaders option to strip sensitive headers before saving.
import { MockAgent, setGlobalDispatcher } from 'undici'const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent)// Closes all mock pools/clients and clears call historyawait mockAgent.close()