11cb0ef41Sopenharmony_ci# Mocking Request
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciUndici has its own mocking [utility](../api/MockAgent.md). It allow us to intercept undici HTTP requests and return mocked values instead. It can be useful for testing purposes.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciExample:
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci```js
81cb0ef41Sopenharmony_ci// bank.mjs
91cb0ef41Sopenharmony_ciimport { request } from 'undici'
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciexport async function bankTransfer(recipient, amount) {
121cb0ef41Sopenharmony_ci  const { body } = await request('http://localhost:3000/bank-transfer',
131cb0ef41Sopenharmony_ci    {
141cb0ef41Sopenharmony_ci      method: 'POST',
151cb0ef41Sopenharmony_ci      headers: {
161cb0ef41Sopenharmony_ci        'X-TOKEN-SECRET': 'SuperSecretToken',
171cb0ef41Sopenharmony_ci      },
181cb0ef41Sopenharmony_ci      body: JSON.stringify({
191cb0ef41Sopenharmony_ci        recipient,
201cb0ef41Sopenharmony_ci        amount
211cb0ef41Sopenharmony_ci      })
221cb0ef41Sopenharmony_ci    }
231cb0ef41Sopenharmony_ci  )
241cb0ef41Sopenharmony_ci  return await body.json()
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci```
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciAnd this is what the test file looks like:
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci```js
311cb0ef41Sopenharmony_ci// index.test.mjs
321cb0ef41Sopenharmony_ciimport { strict as assert } from 'assert'
331cb0ef41Sopenharmony_ciimport { MockAgent, setGlobalDispatcher, } from 'undici'
341cb0ef41Sopenharmony_ciimport { bankTransfer } from './bank.mjs'
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ciconst mockAgent = new MockAgent();
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_cisetGlobalDispatcher(mockAgent);
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci// Provide the base url to the request
411cb0ef41Sopenharmony_ciconst mockPool = mockAgent.get('http://localhost:3000');
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci// intercept the request
441cb0ef41Sopenharmony_cimockPool.intercept({
451cb0ef41Sopenharmony_ci  path: '/bank-transfer',
461cb0ef41Sopenharmony_ci  method: 'POST',
471cb0ef41Sopenharmony_ci  headers: {
481cb0ef41Sopenharmony_ci    'X-TOKEN-SECRET': 'SuperSecretToken',
491cb0ef41Sopenharmony_ci  },
501cb0ef41Sopenharmony_ci  body: JSON.stringify({
511cb0ef41Sopenharmony_ci    recipient: '1234567890',
521cb0ef41Sopenharmony_ci    amount: '100'
531cb0ef41Sopenharmony_ci  })
541cb0ef41Sopenharmony_ci}).reply(200, {
551cb0ef41Sopenharmony_ci  message: 'transaction processed'
561cb0ef41Sopenharmony_ci})
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ciconst success = await bankTransfer('1234567890', '100')
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ciassert.deepEqual(success, { message: 'transaction processed' })
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci// if you dont want to check whether the body or the headers contain the same value
631cb0ef41Sopenharmony_ci// just remove it from interceptor
641cb0ef41Sopenharmony_cimockPool.intercept({
651cb0ef41Sopenharmony_ci  path: '/bank-transfer',
661cb0ef41Sopenharmony_ci  method: 'POST',
671cb0ef41Sopenharmony_ci}).reply(400, {
681cb0ef41Sopenharmony_ci  message: 'bank account not found'
691cb0ef41Sopenharmony_ci})
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ciconst badRequest = await bankTransfer('1234567890', '100')
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciassert.deepEqual(badRequest, { message: 'bank account not found' })
741cb0ef41Sopenharmony_ci```
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ciExplore other MockAgent functionality [here](../api/MockAgent.md)
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci## Debug Mock Value
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ciWhen 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 `mockAgent.disableNetConnect()`:
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci```js
831cb0ef41Sopenharmony_ciconst mockAgent = new MockAgent();
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_cisetGlobalDispatcher(mockAgent);
861cb0ef41Sopenharmony_cimockAgent.disableNetConnect()
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci// Provide the base url to the request
891cb0ef41Sopenharmony_ciconst mockPool = mockAgent.get('http://localhost:3000');
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_cimockPool.intercept({
921cb0ef41Sopenharmony_ci  path: '/bank-transfer',
931cb0ef41Sopenharmony_ci  method: 'POST',
941cb0ef41Sopenharmony_ci}).reply(200, {
951cb0ef41Sopenharmony_ci  message: 'transaction processed'
961cb0ef41Sopenharmony_ci})
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ciconst badRequest = await bankTransfer('1234567890', '100')
991cb0ef41Sopenharmony_ci// Will throw an error
1001cb0ef41Sopenharmony_ci// MockNotMatchedError: Mock dispatch not matched for path '/bank-transfer':
1011cb0ef41Sopenharmony_ci// subsequent request to origin http://localhost:3000 was not allowed (net.connect disabled)
1021cb0ef41Sopenharmony_ci```
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci## Reply with data based on request
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ciIf the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`:
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci```js
1091cb0ef41Sopenharmony_cimockPool.intercept({
1101cb0ef41Sopenharmony_ci  path: '/bank-transfer',
1111cb0ef41Sopenharmony_ci  method: 'POST',
1121cb0ef41Sopenharmony_ci  headers: {
1131cb0ef41Sopenharmony_ci    'X-TOKEN-SECRET': 'SuperSecretToken',
1141cb0ef41Sopenharmony_ci  },
1151cb0ef41Sopenharmony_ci  body: JSON.stringify({
1161cb0ef41Sopenharmony_ci    recipient: '1234567890',
1171cb0ef41Sopenharmony_ci    amount: '100'
1181cb0ef41Sopenharmony_ci  })
1191cb0ef41Sopenharmony_ci}).reply(200, (opts) => {
1201cb0ef41Sopenharmony_ci  // do something with opts
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  return { message: 'transaction processed' }
1231cb0ef41Sopenharmony_ci})
1241cb0ef41Sopenharmony_ci```
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ciin this case opts will be
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci```
1291cb0ef41Sopenharmony_ci{
1301cb0ef41Sopenharmony_ci  method: 'POST',
1311cb0ef41Sopenharmony_ci  headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },
1321cb0ef41Sopenharmony_ci  body: '{"recipient":"1234567890","amount":"100"}',
1331cb0ef41Sopenharmony_ci  origin: 'http://localhost:3000',
1341cb0ef41Sopenharmony_ci  path: '/bank-transfer'
1351cb0ef41Sopenharmony_ci}
1361cb0ef41Sopenharmony_ci```
137