npm nock: mock post 多部分形式上传文件

npm nock: mock post multipart-form uploading file

目标

使用 nock,我正在寻找一种解决方案,通过 POST multipart/form-data.

模拟一个很小的 ​​PNG 文件上传

curl: Box API 上传 PNG 文件

下面的curl脚本介绍了如何upload a file through Box API文件名:'dummy.png'根目录'0' .

curl 'https://upload.box.com/api/2.0/files/content' \
--request POST \
--verbose \
--silent \
--header 'authorization: Bearer [** Access Token **]' \
--header 'Content-Type: multipart/form-data' \
--form attributes='{ "name": "dummy.png", "parent": { "id": "0" } }' \
--form file=@'./files/dummy.png'

简明回复:

Success [HTTP status: 201]
{
  "total_count": 1,
  "entries": [
    {
      "type": "file",
      "name": "dummy.png",
      "id": "584886508967"
    }
  ]
}

诺克尝试:盒子API上传PNG文件

下一个代码片段使用 npm nock 有效,但是,这个模拟是不完整的:

const accessToken = v4();
const randomFileId = v4();
let boundary = '';

const scope = nock('https://upload.box.com/api/2.0/')
  .log((m, d) => logger.debug(m, d))
  .matchHeader('authorization', `Bearer ${accessToken}`);

scope
  .matchHeader('content-type', val => {
    const matches = val.match(/^multipart\/form-data; boundary=([a-zA-Z0-9\-]+)$/);
    if (matches && matches.length > 1) {
      boundary = matches[1];
    }
    return !!matches;
  })
  .post('/files/content', body => {
    return true;
  })
  .reply(201, {
    entries: [
      {
        id: randomFileId,
        name: 'dummy.png',
        type: 'file'
      }
    ]
  });

诺克尝试:缺少表单属性和文件二进制文件

我不清楚如何使用 nock 代码包含 curl POST 请求中包含的内容:

--header 'Content-Type: multipart/form-data' \
--form attributes='{ "name": "dummy.png", "parent": { "id": "0" } }' \
--form file=@'./files/dummy.png'

我想在箭尾中加入 POST 请求:

谢谢,感谢帮助。

正如您在问题中提到的,Nock 不需要表单数据来拦截请求和模拟响应。但是,如果您正在测试您的代码是否发送了正确的请求正文,那么进行断言是一种很好的做法。

--form flag in cURL is a helper 为不同的协议做不同的事情。

For HTTP protocol family, this lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388.

帮助不大,但要点是您在 Nock 中查找的数据将在 POST 请求的正文中。您问题中的 Nock 代码在正确的轨道上。使用回调作为第二个参数的 post 方法是您可以深入了解 Nock 截获的原始数据的方法。不太直接的部分是传递给回调的 body 参数是十六进制编码的,因为正文包含 png 文件的二进制数据。

.post('/files/content', body => {
  const decoded = Buffer.from(body, 'hex');
  console.log(decoded);
  return true;
})

将上面的代码片段添加到您现有的 post 方法应该输出类似于:

----------------------------493956036364114509087826
Content-Disposition: form-data; name="attributes"

{"name":"dummy.png","parent":{"id":"0"}}
----------------------------493956036364114509087826
Content-Disposition: form-data; name="content"; filename="unused"
Content-Type: image/png

�PNG


IHDRĉ
IDATx�c��������IEND�B`�
----------------------------493956036364114509087826--

此时由您决定正文是否包含您期望的数据,return true 如果包含。 参考 RFC 2388 了解多部分表单数据的外观可能会有所帮助。