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

MSW+React-Query+Vitest:前序测试请求在后续测试中失败

解决React Query + MSW测试中的跨测试请求竞态问题

问题核心是测试间状态隔离不足:第一个测试的异步请求在测试结束后未被彻底取消,当第二个测试启动时,这个残留请求仍尝试用旧UUID("fail")发起调用,此时MSW的handler已重置,导致请求失败并产生错误日志。以下是具体解决步骤:

1. 为每个测试创建独立的QueryClient

不要使用全局共享的queryClient,每个测试实例化新的QueryClient,彻底隔离缓存和请求状态:

修改wrappedDetails组件,支持传入自定义QueryClient:

function wrappedDetails(uuid: string, queryClient: QueryClient) {
  return (
    <MemoryRouter initialEntries={["/things/" + uuid]}>
      <QueryClientProvider client={queryClient}>
        <GenericToastProvider>
          <Routes>
            <Route path="/things/:uuid" element={<ThingDetails />}></Route>
          </Routes>
        </GenericToastProvider>
      </QueryClientProvider>
    </MemoryRouter>
  );
}

2. 在测试生命周期中清理请求和缓存

在beforeEach初始化新的QueryClient,在afterEach主动取消所有未完成请求并清空缓存:

describe("Test the view", () => {
  let queryClient: QueryClient;

  beforeEach(() => {
    // 初始化独立的QueryClient,关闭测试环境下的重试避免干扰
    queryClient = new QueryClient({
      defaultOptions: {
        queries: { retry: false }
      }
    });
    server.resetHandlers();
    cleanup();
  });

  afterEach(async () => {
    // 取消所有未完成的异步请求
    await queryClient.cancelQueries();
    // 清空缓存,避免残留状态影响下一个测试
    queryClient.clear();
  });

  // 测试用例...
});

3. 调整MSW handler和组件渲染的顺序

确保先设置当前测试需要的MSW handler,再渲染组件,避免请求发出时handler未生效:

it("DEBUG Handles when rendered with a malformed uuid", async () => {
  const uuid = "fail";

  consoleErrorSpy.mockImplementation(() => {});
  // 先设置对应fail场景的handler
  server.use(...); 
  // 再渲染组件
  render(wrappedDetails(uuid, queryClient));

  await waitFor(
    () => expect(screen.getByText("Encountered an error while fetching")).toBeInTheDocument(),
    { timeout: 10000 }
  );
}, 10000);

it("DEBUG Displays the details that it is supposed to", async () => {
  const uuid = faker.datatype.uuid();

  // 先设置正常场景的handler
  server.use(...); 
  render(wrappedDetails(uuid, queryClient));

  await waitFor(() => expect(screen.getAllByRole("heading", { level: 3 }).length).toBe(1));
});

原理说明

  • 独立QueryClient确保每个测试的React Query状态完全隔离,不会共享缓存或未完成请求。
  • cancelQueries会主动终止所有未完成的请求,避免它们在测试结束后继续执行并干扰后续测试。
  • 调整handler顺序保证请求发出时使用的是当前测试的模拟规则,不会被之前测试的handler影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 01:50:27