如何将FormData字符串转换为JavaScript或JSON对象用于Nock测试
解决方案
问题原因
Nock接收到multipart/form-data类型的请求时,拿到的body是原始的表单序列化字符串,并非结构化的JS对象,你之前直接对原始body做JSON序列化和目标对象比对的逻辑本身也存在语法错误,所以永远无法匹配成功。
实现方法
推荐使用轻量的multipart解析库parse-multipart-data完成转换,步骤如下:
- 安装开发依赖
npm install parse-multipart-data --save-dev
- 修改Nock匹配逻辑
import parse from 'parse-multipart-data'; const submit_claim_request = nock(gatewayClient.defaults.baseURL) .post('/api/v2/claims', function (body, req) { // 从请求头提取boundary const contentType = req.headers['content-type'] || ''; const boundaryMatch = contentType.match(/boundary=(.*)$/); if (!boundaryMatch) return false; const boundary = boundaryMatch[1]; // 解析原始body为结构化字段数组 const parts = parse(Buffer.from(body), boundary); // 转成JS对象方便比对 const formData = {}; parts.forEach(part => { const name = part.name; // 普通字段直接转字符串,文件可以根据需要取filename、data等属性 formData[name] = part.filename ? part : part.data.toString(); }); // 按需比对字段即可,不需要完全匹配可以跳过文件等不需要校验的字段 return formData.default_employee_wallet_id === '0000000046' && Number(formData.amount) === 1 && formData.category === 'Parking' && formData.reimbursement_vendor === 'Test vendor' && formData.transaction_date === '2021-10-03T00:00:00.000Z' && formData.note === 'test description' && formData.is_multi_month === 'false' // 如果需要校验文件可以加下面的逻辑,比如校验文件名 && formData['file[]'].filename === 'chucknorris1.png'; }) .reply(200, { data: { reimbursement: { amount: '1', category: 'Parking', }, }, });
无额外依赖的替代方案
如果不想引入第三方库,也可以使用Node.js内置的busboy模块完成解析,逻辑和上述类似,只是需要自己处理流解析的回调逻辑,适合对性能要求高或者依赖管控严格的场景。
内容的提问来源于stack exchange,提问作者bigpotato
相关产品推荐
相关产品推荐

