MSW中async/await获取FormData无响应,无法完成双场景测试
MSW中读取FormData停滞,无法根据文件名分支返回上传接口响应
我在编写上传组件的测试用例,组件调用https://mydomain/upload接口,需要测试接口返回成功/失败两种场景,计划根据请求FormData里的文件名来区分分支。但目前在MSW中使用await request.formData()时程序会停滞,无法继续执行,导致只能测试一种场景。
相关代码如下:
现有MSW代码
http.post( `https://mydomain/upload`, async ({ request }) => { const info = await request.formData(); console.log('info--------------', info); return HttpResponse.json(bulkUploadErrorResponse.FAILED); } )
现有测试用例代码
test('success message should appear on screen when a correct bulk file is uploaded', async () => { renderWithAllProvider(<MyComponent />); const file = generateXLSXFile('Sample Content', 'testFile'); const fileInput = screen.getByTestId('file-upload'); // eslint-disable-next-line await act(async () => { console.log('Uploading file ......'); await userEvent.upload(fileInput, file); }); // eslint-disable-next-line expect( await screen.findByText( 'Bulk Upload for the inventory has been successfully uploaded!' ) ); });
解决方案
1. 修复MSW中FormData的读取逻辑
确保正确读取FormData中的文件对象,提取文件名后进行分支判断。注意request.formData()返回的是FormData实例,需用get()方法获取文件,再读取name属性。
修改后的MSW代码:
http.post( `https://mydomain/upload`, async ({ request }) => { try { const formData = await request.formData(); // 这里的'file'要和组件中FormData的键名完全一致 const file = formData.get('file'); const fileName = file?.name || ''; // 根据文件名分支返回响应 if (fileName.includes('testFile')) { return HttpResponse.json({ status: 'success' }, { status: 200 }); } else { return HttpResponse.json(bulkUploadErrorResponse.FAILED, { status: 400 }); } } catch (error) { console.error('读取FormData失败:', error); return HttpResponse.json({ error: 'Invalid request' }, { status: 400 }); } } );
2. 简化测试用例中的act包裹
React Testing Library的userEvent.upload本身已处理异步更新,无需手动用act包裹,去掉后可避免不必要的异步阻塞。
修改后的测试用例:
test('success message should appear on screen when a correct bulk file is uploaded', async () => { renderWithAllProvider(<MyComponent />); const file = generateXLSXFile('Sample Content', 'testFile'); const fileInput = screen.getByTestId('file-upload'); console.log('Uploading file ......'); await userEvent.upload(fileInput, file); expect(await screen.findByText( 'Bulk Upload for the inventory has been successfully uploaded!' )).toBeInTheDocument(); }); // 新增失败场景测试用例 test('error message should appear on screen when an invalid file is uploaded', async () => { renderWithAllProvider(<MyComponent />); const file = generateXLSXFile('Invalid Content', 'invalidFile'); const fileInput = screen.getByTestId('file-upload'); await userEvent.upload(fileInput, file); expect(await screen.findByText('Bulk upload failed, please check your file.')).toBeInTheDocument(); });
3. 验证文件生成函数
确保generateXLSXFile能正确生成带指定文件名的File对象,示例实现:
function generateXLSXFile(content, fileName) { const blob = new Blob([content], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); return new File([blob], `${fileName}.xlsx`, { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); }
关键注意点
- 确认组件构造FormData时的键名(如
formData.append('file', file))和MSW中formData.get('file')的键名完全一致,否则无法获取文件。 - 若仍出现停滞,检查测试环境是否有其他请求拦截器干扰,或确认MSW服务器已正确初始化启动。
内容的提问来源于stack exchange,提问作者goku.jin
相关产品推荐
相关产品推荐

