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

如何在React Testing Library中用MSW实现基于请求的动态响应?

如何让Mock Service Worker根据请求动态返回响应?

问题场景

我正在测试一个表单,流程如下:

  • 表单初始通过GET请求加载数据并渲染UI,此时protocol为http,HTTPS单选框未勾选
  • 勾选HTTPS单选框后点击保存,触发PUT请求提交更新后的protocol值
  • 提交完成后,UI会再次发起GET请求刷新数据,我需要此时返回的protocol是PUT提交的https,并验证UI是否正确渲染

当前的MSW mock只能固定返回初始的http,无法根据PUT请求的内容动态更新后续GET响应,请问怎么实现?

解决方案

核心是在测试作用域内维护一个共享状态变量,让PUT请求的mock更新这个变量,GET请求的mock读取这个变量返回响应。修改后的代码如下:

it('should update form and reflect changes on UI', async () => {
  // 定义共享状态,存储当前的protocol值
  let currentProtocol = 'http';

  server.use(
    rest.get(`*/request-to-get-data-and-show on UI`, (_req, res, ctx) => {
      // 每次GET请求都返回当前的protocol值,不要用res.once()
      return res(
        ctx.delay(2000),
        ctx.status(200),
        ctx.json({
          detail: 'ok',
          protocol: currentProtocol, // 使用共享状态的值
          ip: 'fvackq.uksouth.cloudapp.azure.com',
          port: 80,
        })
      );
    }),
    rest.put(`*/request-to-update-db`, (_req, res, ctx) => {
      const data = _req.body as {
        ip: string;
        port: number;
        protocol: string;
      };
      expect(data.protocol).toEqual('https');
      // 更新共享状态为PUT提交的protocol值
      currentProtocol = data.protocol;
      return res(ctx.delay(2000), ctx.status(200));
    })
  );
  
  render(<Settings />);
  const button1 = await screen.findByRole('radio', { name: 'Https', checked: false });
  
  fireEvent.click(button1, { target: { checked: true } });
  await screen.findByRole('radio', { name: 'Https', checked: true });

  const saveButton = screen.getByRole('button', { name: /save/i });
  fireEvent.click(saveButton);

  // 验证第二次GET请求后UI是否正确渲染了https状态
  await screen.findByRole('radio', { name: 'Https', checked: true });
}, 10000);

关键说明

  1. 共享状态的作用域:必须把currentProtocol定义在server.use的外面,确保GET和PUT的mock都能访问并修改它
  2. 移除res.once():原来的res.once()只会响应一次GET请求,后续的请求会失败,所以要去掉,让每次GET请求都能返回最新状态
  3. 状态更新时机:在PUT请求的mock中,验证完请求体后立即更新共享状态,这样后续的GET请求就能拿到最新值
  4. 测试隔离:如果有多组测试,记得在beforeEach中重置currentProtocol的值,避免测试之间的状态污染

内容的提问来源于stack exchange,提问作者hafiz ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:35:25