{
  "type": "module",
  "source": "doc/api/best-practices-mocking-request.md",
  "modules": [
    {
      "textRaw": "Mocking Request",
      "name": "mocking_request",
      "type": "module",
      "desc": "<p>Undici has its own mocking <a href=\"/docs/docs/api/MockAgent.html\">utility</a>. It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.</p>\n<p>Example:</p>\n<pre><code class=\"language-js\">// bank.mjs\nimport { request } from 'undici'\n\nexport async function bankTransfer(recipient, amount) {\n  const { body } = await request('http://localhost:3000/bank-transfer',\n    {\n      method: 'POST',\n      headers: {\n        'X-TOKEN-SECRET': 'SuperSecretToken',\n      },\n      body: JSON.stringify({\n        recipient,\n        amount\n      })\n    }\n  )\n  return await body.json()\n}\n</code></pre>\n<p>And this is what the test file looks like:</p>\n<pre><code class=\"language-js\">// index.test.mjs\nimport { strict as assert } from 'node:assert'\nimport { MockAgent, setGlobalDispatcher, } from 'undici'\nimport { bankTransfer } from './bank.mjs'\n\nconst mockAgent = new MockAgent();\n\nsetGlobalDispatcher(mockAgent);\n\n// Provide the base url to the request\nconst mockPool = mockAgent.get('http://localhost:3000');\n\n// intercept the request\nmockPool.intercept({\n  path: '/bank-transfer',\n  method: 'POST',\n  headers: {\n    'X-TOKEN-SECRET': 'SuperSecretToken',\n  },\n  body: JSON.stringify({\n    recipient: '1234567890',\n    amount: '100'\n  })\n}).reply(200, {\n  message: 'transaction processed'\n})\n\nconst success = await bankTransfer('1234567890', '100')\n\nassert.deepEqual(success, { message: 'transaction processed' })\n\n// if you dont want to check whether the body or the headers contain the same value\n// just remove it from interceptor\nmockPool.intercept({\n  path: '/bank-transfer',\n  method: 'POST',\n}).reply(400, {\n  message: 'bank account not found'\n})\n\nconst badRequest = await bankTransfer('1234567890', '100')\n\nassert.deepEqual(badRequest, { message: 'bank account not found' })\n</code></pre>\n<p>Explore other MockAgent functionality <a href=\"/docs/docs/api/MockAgent.html\">here</a></p>",
      "modules": [
        {
          "textRaw": "Access agent call history",
          "name": "access_agent_call_history",
          "type": "module",
          "desc": "<p>Using a MockAgent also allows you to make assertions on the configuration used to make your request in your application.</p>\n<p>Here is an example :</p>\n<pre><code class=\"language-js\">// index.test.mjs\nimport { strict as assert } from 'node:assert'\nimport { MockAgent, setGlobalDispatcher, fetch } from 'undici'\nimport { app } from './app.mjs'\n\n// given an application server running on http://localhost:3000\nawait app.start()\n\n// enable call history at instantiation\nconst mockAgent = new MockAgent({ enableCallHistory: true })\n// or after instantiation\nmockAgent.enableCallHistory()\n\nsetGlobalDispatcher(mockAgent)\n\n// this call is made (not intercepted)\nawait fetch(`http://localhost:3000/endpoint?query='hello'`, {\n  method: 'POST',\n  headers: { 'content-type': 'application/json' }\n  body: JSON.stringify({ data: '' })\n})\n\n// access to the call history of the MockAgent (which register every call made intercepted or not)\nassert.ok(mockAgent.getCallHistory()?.calls().length === 1)\nassert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.fullUrl, `http://localhost:3000/endpoint?query='hello'`)\nassert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.body, JSON.stringify({ data: '' }))\nassert.deepStrictEqual(mockAgent.getCallHistory()?.firstCall()?.searchParams, { query: 'hello' })\nassert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.port, '3000')\nassert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.host, 'localhost:3000')\nassert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.method, 'POST')\nassert.strictEqual(mockAgent.getCallHistory()?.firstCall()?.path, '/endpoint')\nassert.deepStrictEqual(mockAgent.getCallHistory()?.firstCall()?.headers, { 'content-type': 'application/json' })\n\n// clear all call history logs\nmockAgent.clearCallHistory()\n\nassert.ok(mockAgent.getCallHistory()?.calls().length === 0)\n</code></pre>\n<p>Calling <code>mockAgent.close()</code> will automatically clear and delete every call history for you.</p>\n<p>Explore other MockAgent functionality <a href=\"/docs/docs/api/MockAgent.html\">here</a></p>\n<p>Explore other MockCallHistory functionality <a href=\"/docs/docs/api/MockCallHistory.html\">here</a></p>\n<p>Explore other MockCallHistoryLog functionality <a href=\"/docs/docs/api/MockCallHistoryLog.html\">here</a></p>",
          "displayName": "Access agent call history"
        },
        {
          "textRaw": "Debug Mock Value",
          "name": "debug_mock_value",
          "type": "module",
          "desc": "<p>When the interceptor and the request options are not the same, undici will automatically make a real HTTP request. To prevent real requests from being made, use <code>mockAgent.disableNetConnect()</code>:</p>\n<pre><code class=\"language-js\">const mockAgent = new MockAgent();\n\nsetGlobalDispatcher(mockAgent);\nmockAgent.disableNetConnect()\n\n// Provide the base url to the request\nconst mockPool = mockAgent.get('http://localhost:3000');\n\nmockPool.intercept({\n  path: '/bank-transfer',\n  method: 'POST',\n}).reply(200, {\n  message: 'transaction processed'\n})\n\nconst badRequest = await bankTransfer('1234567890', '100')\n// Will throw an error\n// MockNotMatchedError: Mock dispatch not matched for path '/bank-transfer':\n// subsequent request to origin http://localhost:3000 was not allowed (net.connect disabled)\n</code></pre>",
          "displayName": "Debug Mock Value"
        },
        {
          "textRaw": "Reply with data based on request",
          "name": "reply_with_data_based_on_request",
          "type": "module",
          "desc": "<p>If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to <code>reply</code>:</p>\n<pre><code class=\"language-js\">mockPool.intercept({\n  path: '/bank-transfer',\n  method: 'POST',\n  headers: {\n    'X-TOKEN-SECRET': 'SuperSecretToken',\n  },\n  body: JSON.stringify({\n    recipient: '1234567890',\n    amount: '100'\n  })\n}).reply(200, (opts) => {\n  // do something with opts\n\n  return { message: 'transaction processed' }\n})\n</code></pre>\n<p>in this case opts will be</p>\n<pre><code>{\n  method: 'POST',\n  headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },\n  body: '{\"recipient\":\"1234567890\",\"amount\":\"100\"}',\n  origin: 'http://localhost:3000',\n  path: '/bank-transfer'\n}\n</code></pre>",
          "displayName": "Reply with data based on request"
        }
      ],
      "displayName": "Mocking Request"
    }
  ]
}