You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:02:15