File Explorer

/proc/self/root/proc/1/cwd/node24/lib/node_modules/npm/node_modules/undici/docs/docs/api

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

MockPool.md15.8 KB · 548 lines
# Class: MockPool Extends: `undici.Pool` A mock Pool class that implements the Pool API and is used by MockAgent to intercept real requests and return mocked responses. ## `new MockPool(origin, [options])` Arguments: * **origin** `string` - It should only include the **protocol, hostname, and port**.* **options** `MockPoolOptions` - It extends the `Pool` options. Returns: `MockPool` ### Parameter: `MockPoolOptions` Extends: `PoolOptions` * **agent** `Agent` - the agent to associate this MockPool with. ### Example - Basic MockPool instantiation We can use MockAgent to instantiate a MockPool ready to be used to intercept specified requests. It will not do anything until registered as the agent to use and any mock request are registered. ```jsimport { MockAgent } from 'undici' const mockAgent = new MockAgent() const mockPool = mockAgent.get('http://localhost:3000')``` ## Instance Methods ### `MockPool.intercept(options)` This method defines the interception rules for matching against requests for a MockPool or MockPool. We can intercept multiple times on a single instance, but each intercept is only used once. For example if you expect to make 2 requests inside a test, you need to call `intercept()` twice. Assuming you use `disableNetConnect()` you will get `MockNotMatchedError` on the second request when you only call `intercept()` once. When defining interception rules, all the rules must pass for a request to be intercepted. If a request is not intercepted, a real request will be attempted. | Matcher type | Condition to pass          ||:------------:| -------------------------- || `string`     | Exact match against string || `RegExp`     | Regex must pass            || `Function`   | Function must return true  | Arguments: * **options** `MockPoolInterceptOptions` - Interception options. Returns: `MockInterceptor` corresponding to the input options. ### Parameter: `MockPoolInterceptOptions` * **path** `string | RegExp | (path: string) => boolean` - a matcher for the HTTP request path. When a `RegExp` or callback is used, it will match against the request path including all query parameters in alphabetical order. When a `string` is provided, the query parameters can be conveniently specified through the `MockPoolInterceptOptions.query` setting.* **method** `string | RegExp | (method: string) => boolean` - (optional) - a matcher for the HTTP request method. Defaults to `GET`.* **body** `string | RegExp | (body: string) => boolean` - (optional) - a matcher for the HTTP request body.* **headers** `Record<string, string | RegExp | (body: string) => boolean`> - (optional) - a matcher for the HTTP request headers. To be intercepted, a request must match all defined headers. Extra headers not defined here may (or may not) be included in the request and do not affect the interception in any way.* **query** `Record<string, any> | null` - (optional) - a matcher for the HTTP request query string params. Only applies when a `string` was provided for `MockPoolInterceptOptions.path`. ### Return: `MockInterceptor` We can define the behaviour of an intercepted request with the following options. * **reply** `(statusCode: number, replyData: string | Buffer | object | MockInterceptor.MockResponseDataHandler, responseOptions?: MockResponseOptions) => MockScope` - define a reply for a matching request. You can define the replyData as a callback to read incoming request data. Default for `responseOptions` is `{}`.* **reply** `(callback: MockInterceptor.MockReplyOptionsCallback) => MockScope` - define a reply for a matching request, allowing dynamic mocking of all reply options rather than just the data.* **replyWithError** `(error: Error) => MockScope` - define an error for a matching request to throw.* **defaultReplyHeaders** `(headers: Record<string, string>) => MockInterceptor` - define default headers to be included in subsequent replies. These are in addition to headers on a specific reply.* **defaultReplyTrailers** `(trailers: Record<string, string>) => MockInterceptor` - define default trailers to be included in subsequent replies. These are in addition to trailers on a specific reply.* **replyContentLength** `() => MockInterceptor` - define automatically calculated `content-length` headers to be included in subsequent replies. The reply data of an intercepted request may either be a string, buffer, or JavaScript object. Objects are converted to JSON while strings and buffers are sent as-is. By default, `reply` and `replyWithError` define the behaviour for the first matching request only. Subsequent requests will not be affected (this can be changed using the returned `MockScope`). ### Parameter: `MockResponseOptions` * **headers** `Record<string, string>` - headers to be included on the mocked reply.* **trailers** `Record<string, string>` - trailers to be included on the mocked reply. ### Return: `MockScope` A `MockScope` is associated with a single `MockInterceptor`. With this, we can configure the default behaviour of a intercepted reply. * **delay** `(waitInMs: number) => MockScope` - delay the associated reply by a set amount in ms.* **persist** `() => MockScope` - any matching request will always reply with the defined response indefinitely.* **times** `(repeatTimes: number) => MockScope` - any matching request will reply with the defined response a fixed amount of times. This is overridden by **persist**. #### Example - Basic Mocked Request ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) // MockPoolconst 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 200 for await (const data of body) {  console.log('data', data.toString('utf8')) // data foo}``` #### Example - Mocked request using reply data callbacks ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/echo',  method: 'GET',  headers: {    'User-Agent': 'undici',    Host: 'example.com'  }}).reply(200, ({ headers }) => ({ message: headers.get('message') })) const { statusCode, body, headers } = await request('http://localhost:3000', {  headers: {    message: 'hello world!'  }}) console.log('response received', statusCode) // response received 200console.log('headers', headers) // { 'content-type': 'application/json' } for await (const data of body) {  console.log('data', data.toString('utf8')) // { "message":"hello world!" }}``` #### Example - Mocked request using reply options callback ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/echo',  method: 'GET',  headers: {    'User-Agent': 'undici',    Host: 'example.com'  }}).reply(({ headers }) => ({ statusCode: 200, data: { message: headers.get('message') }}))) const { statusCode, body, headers } = await request('http://localhost:3000', {  headers: {    message: 'hello world!'  }}) console.log('response received', statusCode) // response received 200console.log('headers', headers) // { 'content-type': 'application/json' } for await (const data of body) {  console.log('data', data.toString('utf8')) // { "message":"hello world!" }}``` #### Example - Basic Mocked requests with multiple intercepts ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).reply(200, 'foo') mockPool.intercept({  path: '/hello',  method: 'GET',}).reply(200, 'hello') const result1 = await request('http://localhost:3000/foo') console.log('response received', result1.statusCode) // response received 200 for await (const data of result1.body) {  console.log('data', data.toString('utf8')) // data foo} const result2 = await request('http://localhost:3000/hello') console.log('response received', result2.statusCode) // response received 200 for await (const data of result2.body) {  console.log('data', data.toString('utf8')) // data hello}``` #### Example - Mocked request with query body, request headers and response headers and trailers ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo?hello=there&see=ya',  method: 'POST',  body: 'form1=data1&form2=data2',  headers: {    'User-Agent': 'undici',    Host: 'example.com'  }}).reply(200, { foo: 'bar' }, {  headers: { 'content-type': 'application/json' },  trailers: { 'Content-MD5': 'test' }}) const {  statusCode,  headers,  trailers,  body} = await request('http://localhost:3000/foo?hello=there&see=ya', {    method: 'POST',    body: 'form1=data1&form2=data2',    headers: {      foo: 'bar',      'User-Agent': 'undici',      Host: 'example.com'    }  }) console.log('response received', statusCode) // response received 200console.log('headers', headers) // { 'content-type': 'application/json' } for await (const data of body) {  console.log('data', data.toString('utf8')) // '{"foo":"bar"}'} console.log('trailers', trailers) // { 'content-md5': 'test' }``` #### Example - Mocked request using different matchers ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: /^GET$/,  body: (value) => value === 'form=data',  headers: {    'User-Agent': 'undici',    Host: /^example.com$/  }}).reply(200, 'foo') const {  statusCode,  body} = await request('http://localhost:3000/foo', {  method: 'GET',  body: 'form=data',  headers: {    foo: 'bar',    'User-Agent': 'undici',    Host: 'example.com'  }}) console.log('response received', statusCode) // response received 200 for await (const data of body) {  console.log('data', data.toString('utf8')) // data foo}``` #### Example - Mocked request with reply with a defined error ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).replyWithError(new Error('kaboom')) try {  await request('http://localhost:3000/foo', {    method: 'GET'  })} catch (error) {  console.error(error) // Error: kaboom}``` #### Example - Mocked request with defaultReplyHeaders ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).defaultReplyHeaders({ foo: 'bar' })  .reply(200, 'foo') const { headers } = await request('http://localhost:3000/foo') console.log('headers', headers) // headers { foo: 'bar' }``` #### Example - Mocked request with defaultReplyTrailers ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).defaultReplyTrailers({ foo: 'bar' })  .reply(200, 'foo') const { trailers } = await request('http://localhost:3000/foo') console.log('trailers', trailers) // trailers { foo: 'bar' }``` #### Example - Mocked request with automatic content-length calculation ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).replyContentLength().reply(200, 'foo') const { headers } = await request('http://localhost:3000/foo') console.log('headers', headers) // headers { 'content-length': '3' }``` #### Example - Mocked request with automatic content-length calculation on an object ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).replyContentLength().reply(200, { foo: 'bar' }) const { headers } = await request('http://localhost:3000/foo') console.log('headers', headers) // headers { 'content-length': '13' }``` #### Example - Mocked request with persist enabled ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).reply(200, 'foo').persist() const result1 = await request('http://localhost:3000/foo')// Will match and return mocked data const result2 = await request('http://localhost:3000/foo')// Will match and return mocked data // Etc``` #### Example - Mocked request with times enabled ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') mockPool.intercept({  path: '/foo',  method: 'GET'}).reply(200, 'foo').times(2) const result1 = await request('http://localhost:3000/foo')// Will match and return mocked data const result2 = await request('http://localhost:3000/foo')// Will match and return mocked data const result3 = await request('http://localhost:3000/foo')// Will not match and make attempt a real request``` #### Example - Mocked request with path callback ```jsimport { MockAgent, setGlobalDispatcher, request } from 'undici'import querystring from 'querystring' const mockAgent = new MockAgent()setGlobalDispatcher(mockAgent) const mockPool = mockAgent.get('http://localhost:3000') const matchPath = requestPath => {  const [pathname, search] = requestPath.split('?')  const requestQuery = querystring.parse(search)   if (!pathname.startsWith('/foo')) {    return false  }   if (!Object.keys(requestQuery).includes('foo') || requestQuery.foo !== 'bar') {    return false  }   return true} mockPool.intercept({  path: matchPath,  method: 'GET'}).reply(200, 'foo') const result = await request('http://localhost:3000/foo?foo=bar')// Will match and return mocked data``` ### `MockPool.close()` Closes the mock pool and de-registers from associated MockAgent. Returns: `Promise<void>` #### Example - clean up after tests are complete ```jsimport { MockAgent } from 'undici' const mockAgent = new MockAgent()const mockPool = mockAgent.get('http://localhost:3000') await mockPool.close()``` ### `MockPool.dispatch(options, handlers)` Implements [`Dispatcher.dispatch(options, handlers)`](Dispatcher.md#dispatcherdispatchoptions-handler). ### `MockPool.request(options[, callback])` See [`Dispatcher.request(options [, callback])`](Dispatcher.md#dispatcherrequestoptions-callback). #### Example - MockPool request ```jsimport { MockAgent } from 'undici' const mockAgent = new MockAgent() const mockPool = mockAgent.get('http://localhost:3000')mockPool.intercept({  path: '/foo',  method: 'GET',}).reply(200, 'foo') const {  statusCode,  body} = await mockPool.request({  origin: 'http://localhost:3000',  path: '/foo',  method: 'GET'}) console.log('response received', statusCode) // response received 200 for await (const data of body) {  console.log('data', data.toString('utf8')) // data foo}```