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

使用Jest与MSW测试RTK Query Hook时请求拦截失败问题

问题:Jest+MSW测试RTK Query Hook时请求未被拦截,组件显示错误文本

测试RTK Query的useGetTaxSystemQuery Hook时,MSW无法正确拦截请求,组件未渲染预期复选框,反而显示错误文本“Ошибка”,测试报错Unable to find an element by: [data-testid="test1"]。单独用fetch请求${process.env.API_URL}/dict/taxSystem能拿到模拟数据,但RTK Query Hook无法获取数据,导致组件进入错误分支。

核心问题排查

1. RTK Query响应结构不匹配

RTK Query的getTaxSystem配置中,transformResponse期望接收IFullResponse<ITaxSystem[]>类型的响应(即包含response字段的对象),但当前MSW直接返回了数组mockTaxSystem,导致transformResponse处理后返回undefined,最终taxSystemData为undefined,组件触发错误分支。

2. 请求路径匹配问题

RTK Query的API实例(app/api)可能配置了baseURL,如果实际请求路径是${baseURL}/dict/taxSystem,而MSW的handler仅匹配/dict/taxSystem,会导致请求未被拦截,返回真实接口的错误响应。

解决方案

修复MSW响应结构

修改dictionariesHandlers,返回符合IFullResponse结构的数据:

// handlers.ts
export const dictionariesHandlers = [
  rest.get(`/dict/taxSystem`, (_, res, ctx) =>
    res(ctx.status(200), ctx.json({ response: mockTaxSystem }))
  ),
];

确保请求路径匹配

  • 检查app/api中的baseURL配置,若测试环境baseURL不为/,则修改MSW handler的路径为完整匹配:
    // 假设process.env.API_URL在测试环境为'/api'
    rest.get(`${process.env.API_URL}/dict/taxSystem`, (_, res, ctx) =>
      res(ctx.status(200), ctx.json({ response: mockTaxSystem }))
    ),
    
  • 或在测试环境配置baseURL为/,确保请求路径与MSW handler匹配。

优化测试用例

使用异步查询方法findByTestId替代getByTestId,避免同步查询导致的错误:

it('should display taxation system', async () => {
  const { findByTestId, queryByText } = renderTestApp(<TestComponent />);

  expect(queryByText(/loading.../i)).toBeInTheDocument();

  // 异步等待元素出现
  const test1Checkbox = await findByTestId('test1');
  expect(test1Checkbox).toBeInTheDocument();

  expect(queryByText(/loading.../i)).not.toBeInTheDocument();
});

可选:完善组件错误状态处理

组件当前仅判断taxSystemData?.length,可添加isError状态判断,更清晰区分加载、成功、错误状态:

const TestComponent = () => {
  const { data: taxSystemData, isLoading, isError } = useGetTaxSystemQuery();

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (isError) {
    return <div data-testid="error">Ошибка</div>;
  }

  return (
    <div data-testid="TaxationSystems">
      {taxSystemData?.length ? (
        <div>
          {taxSystemData.map((item) => (
            <FormCheckbox
              data-testid={item.value}
              key={item.id}
              label={item.name}
              name={item.value}
            />
          ))}
        </div>
      ) : (
        <div data-testid="empty">Нет данных</div>
      )}
    </div>
  );
};

内容的提问来源于stack exchange,提问作者IT Punisher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 14:36:13