undici icon indicating copy to clipboard operation
undici copied to clipboard

MockAgent don't intercept Pool requests

Open santiagoalmeidabolannos opened this issue 3 years ago • 7 comments

Check this example based on these docs https://undici.nodejs.org/#/docs/api/MockPool?id=example-basic-mockpool-instantiation

When

const { MockAgent, setGlobalDispatcher, Pool } = require('undici')

const mockAgent = new MockAgent()

setGlobalDispatcher(mockAgent)

const mockPool = mockAgent.get('https://jsonplaceholder.typicode.com')


mockPool.intercept({
 path: '/todos/1',
 method: 'GET'
}).reply(200, 'foo')

async function run () {
   try {
       const agent = new Pool('https://jsonplaceholder.typicode.com', {
           headersTimeout: 30e3, // 30 seconds
           maxHeaderSize: 16_384, // 16 KiB
           keepAliveMaxTimeout: 5000, // 5 seconds
           connections: 50,
           tls: { rejectUnauthorized: false },
       })

       const { statusCode, body } = await agent.request({
           path: '/todos/1',
           method: 'GET',
       })

       console.log('response received', statusCode) // response received 200

       for await (const data of body) {
           console.log('data', data.toString('utf8')) // data foo
       }
   }
   catch (error) {
       console.log(error)
   }
}

run()

The request never gets intercepted, not sure if I am missing something here

santiagoalmeidabolannos avatar Aug 24 '21 08:08 santiagoalmeidabolannos

It doesn't and that's the point. Just pass in the agent instead of your pool instance. There is no monkeypatching involved.

mcollina avatar Aug 24 '21 08:08 mcollina

Hiya 👋

Currently working on migrating some code from node-fetch&nock to undici, and I think I'm hitting something similar to this.

I have a certificate to use, therefore I must (I think?) create a Client rather than using the request export. But then setting the global dispatcher etc doesn't seem to have an effect. Is this expected? Or is it only possible to mock requests made with the request export? None of the examples in the docs seems to use anything else.

How would I go about mocking a request which is made using a Client? From your response it seems I need to pass something in where the new Client call is. But the Client constructor doesn't take a dispatcher argument or some such, so I'm not sure how that'd help me?

(I've only tried to use Undici for about an hour now, so I assume I'm just missing something 😅)

SimenB avatar Aug 24 '21 14:08 SimenB

I would recommend you to structure/test your code like the following:

  1. a function that build the Client (or Pool) instance, let's call it build()
  2. a function that takes a Client/Pool and use it to make that request, let's call it execute()
  3. create a MockClient/MockPool and pass it to the second function, e.g. execute(build())

On a side note we probably need a way to specify those client credentials in some global way, the Client/Pool instances are really too low level for most folks.

mcollina avatar Aug 24 '21 15:08 mcollina

This needs better docs.

mcollina avatar Aug 24 '21 15:08 mcollina