source: node_modules/undici/docs/best-practices/mocking-request.md@ d24f17c

main
Last change on this file since d24f17c was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 3.3 KB
RevLine 
[d24f17c]1# Mocking Request
2
3Undici 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.
4
5Example:
6
7```js
8// bank.mjs
9import { request } from 'undici'
10
11export async function bankTransfer(recipient, amount) {
12 const { body } = await request('http://localhost:3000/bank-transfer',
13 {
14 method: 'POST',
15 headers: {
16 'X-TOKEN-SECRET': 'SuperSecretToken',
17 },
18 body: JSON.stringify({
19 recipient,
20 amount
21 })
22 }
23 )
24 return await body.json()
25}
26```
27
28And this is what the test file looks like:
29
30```js
31// index.test.mjs
32import { strict as assert } from 'assert'
33import { MockAgent, setGlobalDispatcher, } from 'undici'
34import { bankTransfer } from './bank.mjs'
35
36const mockAgent = new MockAgent();
37
38setGlobalDispatcher(mockAgent);
39
40// Provide the base url to the request
41const mockPool = mockAgent.get('http://localhost:3000');
42
43// intercept the request
44mockPool.intercept({
45 path: '/bank-transfer',
46 method: 'POST',
47 headers: {
48 'X-TOKEN-SECRET': 'SuperSecretToken',
49 },
50 body: JSON.stringify({
51 recipient: '1234567890',
52 amount: '100'
53 })
54}).reply(200, {
55 message: 'transaction processed'
56})
57
58const success = await bankTransfer('1234567890', '100')
59
60assert.deepEqual(success, { message: 'transaction processed' })
61
62// if you dont want to check whether the body or the headers contain the same value
63// just remove it from interceptor
64mockPool.intercept({
65 path: '/bank-transfer',
66 method: 'POST',
67}).reply(400, {
68 message: 'bank account not found'
69})
70
71const badRequest = await bankTransfer('1234567890', '100')
72
73assert.deepEqual(badRequest, { message: 'bank account not found' })
74```
75
76Explore other MockAgent functionality [here](../api/MockAgent.md)
77
78## Debug Mock Value
79
80When 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()`:
81
82```js
83const mockAgent = new MockAgent();
84
85setGlobalDispatcher(mockAgent);
86mockAgent.disableNetConnect()
87
88// Provide the base url to the request
89const mockPool = mockAgent.get('http://localhost:3000');
90
91mockPool.intercept({
92 path: '/bank-transfer',
93 method: 'POST',
94}).reply(200, {
95 message: 'transaction processed'
96})
97
98const badRequest = await bankTransfer('1234567890', '100')
99// Will throw an error
100// MockNotMatchedError: Mock dispatch not matched for path '/bank-transfer':
101// subsequent request to origin http://localhost:3000 was not allowed (net.connect disabled)
102```
103
104## Reply with data based on request
105
106If the mocked response needs to be dynamically derived from the request parameters, you can provide a function instead of an object to `reply`:
107
108```js
109mockPool.intercept({
110 path: '/bank-transfer',
111 method: 'POST',
112 headers: {
113 'X-TOKEN-SECRET': 'SuperSecretToken',
114 },
115 body: JSON.stringify({
116 recipient: '1234567890',
117 amount: '100'
118 })
119}).reply(200, (opts) => {
120 // do something with opts
121
122 return { message: 'transaction processed' }
123})
124```
125
126in this case opts will be
127
128```
129{
130 method: 'POST',
131 headers: { 'X-TOKEN-SECRET': 'SuperSecretToken' },
132 body: '{"recipient":"1234567890","amount":"100"}',
133 origin: 'http://localhost:3000',
134 path: '/bank-transfer'
135}
136```
Note: See TracBrowser for help on using the repository browser.