如何模拟Node.js在节点18中获取HTTP请求/响应?

0md85ypi  于 2022-12-03  发布在  Node.js
关注(0)|答案(1)|浏览(166)

我正在使用新的(从版本18开始)Node.js“fetch”API来执行HTTP请求,例如:

const response = await fetch(SOMEURL)
const json = await response.json()

这是可行的,但是我想“模拟”那些HTTP请求,以便我可以进行一些自动化测试,并能够模拟一些HTTP响应,以查看我的代码是否正常工作。
通常,我使用Axios和优秀的nock包来模拟HTTP请求,但它似乎不适用于节点18中的fetch
那么,在Node.js中使用fetch时,如何模拟HTTP请求和响应呢?

mzillmmw

mzillmmw1#

Node 18's fetch function isn't built on the Node.js http module like most HTTP libraries (including Axios, request etc) - it's a total rewrite of an HTTP client built on the lower-level "net" library called undici . As such, "nock" cannot intercept requests made from the fetch function (I believe the team are looking to fix this, but at the time of writing, Nock 13.2.9, Nock does not work for fetch requests).
The solution is to use a MockAgent that is built into the undici package.
Let's say your code looks like this:

// constants
const U = 'http://127.0.0.1:5984'
const DB = 'users'

const main = async () => {

  // perform request
  const r = await fetch(U + '/' + DB)

  // parse response as JSON
  const j = await r.json()
  console.log(j)
}

main()

This code makes a real HTTP request to a CouchDB server running on localhost.
To mock this request, we need to add undici into our project:

npm install --save-dev undici

and add some code to intercept the request:

// constants
const U = 'http://127.0.0.1:5984'
const DB = 'users'

// set up mocking of HTTP requests
const { MockAgent, setGlobalDispatcher } = require('undici')
const mockAgent = new MockAgent()
const mockPool = mockAgent.get(U)
setGlobalDispatcher(mockAgent)

const main = async () => {
  // intercept GET /users requests
  mockPool.intercept({ path: '/' + DB }).reply(200, { ok: true })

  // perform request
  const r = await fetch(U + '/' + DB,)

  // parse response as JSON
  const j = await r.json()
  console.log(j)
}

main()

The above code now has its HTTP "fetch" request intercepted with mocked response.

相关问题