简体   繁体   English

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

[英]How do I mock Node.js fetch HTTP requests/responses in Node 18?

I am using the new (as of version 18) Node.js "fetch" API to perform HTTP requests eg我正在使用新的(从版本 18 开始)Node.js“获取”API 来执行 HTTP 请求,例如

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

This works, but I want to "mock" those HTTP requests so that I can do some automated testing and be able to simulate some HTTP responses to see if my code works correctly.这可行,但我想“模拟”那些 HTTP 请求,以便我可以进行一些自动化测试并能够模拟一些 HTTP 响应以查看我的代码是否正常工作。

Normally I have used the excellent nock package alongside Axios to mock HTTP requests, but it doesn't appear to work with fetch in Node 18.通常我使用优秀的nock package 和 Axios 来模拟 HTTP 请求,但它似乎不适用于 Node 18 中的fetch

So how can I mock HTTP requests and responses when using fetch in Node.js?那么在 Node.js 中使用fetch时如何模拟 HTTP 请求和响应呢?

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). Node 18 的fetch function 不像大多数 HTTP 库(包括 Axios、请求等)那样构建在 Node.js http模块上(包括 Axios、request 等)——它是对 HTTP 库的完全重写——它是一个 HTTP 库的完全重写,称为unlevel库,构建在 .net 上的 unlevel 客户端。 nock" 无法拦截来自fetch function 的请求(我相信团队正在寻求解决此问题,但在撰写本文时,Nock 13.2.9,Nock 不适用于fetch请求)。

The solution is to use a MockAgent that is built into the undici package.解决方案是使用内置于undici package 中的 MockAgent。

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.此代码向在本地主机上运行的 CouchDB 服务器发出真正的 HTTP 请求。

To mock this request, we need to add undici into our project:要模拟此请求,我们需要将undici添加到我们的项目中:

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.上面的代码现在有它的 HTTP “获取”请求被模拟响应拦截。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM