From 16ab2c98a01d526750dc0d235f5db0c0b8369d33 Mon Sep 17 00:00:00 2001 From: Oliver Salzburg Date: Mon, 20 Nov 2023 20:45:54 +0100 Subject: [PATCH] docs: Clarify `path` matching in `intercept()` (#2426) The behavior of `query` was unclear, as it only applies to the case where `path` is provided as a `string`. It also wasn't clear that the `RegExp` and callback case will receive the query as part of the path. The additional guidance should help with both. To further clarify the use case, an example for the callback scenario was added. Closes: #2385 --- docs/api/MockPool.md | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/api/MockPool.md b/docs/api/MockPool.md index de53914002e..96a986f57bb 100644 --- a/docs/api/MockPool.md +++ b/docs/api/MockPool.md @@ -35,8 +35,7 @@ const mockPool = mockAgent.get('http://localhost:3000') ### `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. +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. @@ -54,11 +53,11 @@ Returns: `MockInterceptor` corresponding to the input options. ### Parameter: `MockPoolInterceptOptions` -* **path** `string | RegExp | (path: string) => boolean` - a matcher for the HTTP request path. +* **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 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 | null` - (optional) - a matcher for the HTTP request query string params. +* **query** `Record | null` - (optional) - a matcher for the HTTP request query string params. Only applies when a `string` was provided for `MockPoolInterceptOptions.path`. ### Return: `MockInterceptor` @@ -458,6 +457,41 @@ const result3 = await request('http://localhost:3000/foo') // Will not match and make attempt a real request ``` +#### Example - Mocked request with path callback + +```js +import { 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.