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

ReactJS中MSW测试接口响应重叠导致测试失败求助

MSW测试中接口响应被覆盖的问题解决

问题现象

使用MSW模拟API接口进行React组件测试时,第二个测试始终获取第一个测试的成功响应,导致断言失败;移除第一个测试后,第二个测试可正常运行,即使使用res.once()也无效。

测试代码示例:

// ...import section

test('Should component render successfully', () => {
    server.use(
      rest.get(
        `${process.env.REACT_APP_API_ENDPOINT}/api/discount`,
        (req, res, ctx) => {
          return res(ctx.status(200), ctx.json({ data: DiscountMockData.vouchers[0] }));
        }
      )
    );
    
    render(<MyComponent />);
    
    expect(screen.getByTestId('result')).toBeInTheDocumment();
});

test('Should component render failed because of API response', () => {
    server.use(
      rest.get(
        `${process.env.REACT_APP_API_ENDPOINT}/api/discount`,
        (req, res, ctx) => {
          return res(ctx.status(400), ctx.json({}));
        }
      )
    );
    
    render(<MyComponent />);
    
    expect(screen.getByTestId('error')).toBeInTheDocumment();
})

问题原因

MSW的server.use()方法是追加请求处理器,而非替换。第一个测试添加的处理器会保留在服务器实例中,第二个测试再次调用server.use()时,新的处理器会排在已有处理器之后;当接口请求触发时,MSW会匹配第一个符合条件的处理器,因此第二个测试仍会使用第一个测试的成功响应。

解决方法

方法1:全局设置测试后重置处理器

在测试文件中添加afterEach钩子,调用server.resetHandlers()清空所有请求处理器,确保每个测试环境都是独立的:

// ...import section

afterEach(() => {
  server.resetHandlers();
});

test('Should component render successfully', () => {
    server.use(
      rest.get(
        `${process.env.REACT_APP_API_ENDPOINT}/api/discount`,
        (req, res, ctx) => {
          return res(ctx.status(200), ctx.json({ data: DiscountMockData.vouchers[0] }));
        }
      )
    );
    
    render(<MyComponent />);
    
    expect(screen.getByTestId('result')).toBeInTheDocument(); // 修正拼写错误
});

test('Should component render failed because of API response', () => {
    server.use(
      rest.get(
        `${process.env.REACT_APP_API_ENDPOINT}/api/discount`,
        (req, res, ctx) => {
          return res(ctx.status(400), ctx.json({}));
        }
      )
    );
    
    render(<MyComponent />);
    
    expect(screen.getByTestId('error')).toBeInTheDocument(); // 修正拼写错误
})

方法2:单个测试内先重置再添加处理器

如果不需要全局重置,可在目标测试的开头手动调用server.resetHandlers()清空之前的处理器:

test('Should component render failed because of API response', () => {
    server.resetHandlers(); // 先清空历史处理器
    server.use(
      rest.get(
        `${process.env.REACT_APP_API_ENDPOINT}/api/discount`,
        (req, res, ctx) => {
          return res(ctx.status(400), ctx.json({}));
        }
      )
    );
    
    render(<MyComponent />);
    
    expect(screen.getByTestId('error')).toBeInTheDocument();
})

额外注意

代码中的toBeInTheDocumment是拼写错误,正确应为toBeInTheDocument,这个错误也会导致测试断言失败,需要一并修正。

内容的提问来源于stack exchange,提问作者Viet Nguyen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:35:20