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

如何用Sinon Stub模拟React自定义Hook并解决相关报错

问题解决方案

一、用Sinon正确模拟React自定义Hook

你的错误根源是直接在组件外部调用React Hook,违反了Hook的使用规则。正确的做法是Stub整个Hook的导出模块,让组件在测试时调用我们的Mock版本,而非真实Hook。

实现代码

import * as useApiDataModule from "../path/to/your/useApiData"; // 替换为Hook的实际路径

export function mockGetCase(sinonSandbox: SinonSandbox = sinon.createSandbox()) {
  // 模拟useQuery的返回结构(组件会依赖这些属性)
  const mockUseQueryResult = {
    data: caseMockApiData,
    isLoading: false,
    isSuccess: true,
    error: null
    // 可根据组件实际使用的属性补充
  };

  // Stub Hook的getCase方法
  const mockGetCase = sinonSandbox.stub().returns(mockUseQueryResult);

  // Stub整个useApiData Hook的返回值
  sinonSandbox.stub(useApiDataModule, "useApiData").returns({
    api: { getCase: mockGetCase },
    networkError: null
  });

  return sinonSandbox;
}

关键说明

  • 不要直接调用useApiData(),而是通过Stub模块导出的方式,替换Hook的实现
  • 模拟的getCase必须返回符合useQuery的结构(而非直接返回Promise),因为原Hook中getCase的返回值是useQuery的结果对象

二、解决MSW的绝对URL错误

报错是因为两个原因:getSecurityTokenForApp中的相对路径请求未被拦截,且API地址可能未使用绝对路径。

修复步骤

  1. 拦截/token请求:在MSW中添加对token接口的模拟,避免真实请求触发错误
  2. 确保API地址为绝对路径:检查environment.url.case是否为完整的绝对URL(如https://your-api-domain/case)

修正后的MSW代码

const server = setupServer(
  // 模拟案件接口
  rest.get(`${environment.url.case}/api/case/:caseId`, (req, res, ctx) => {
    return res(ctx.json(caseMockApiData));
  }),
  // 模拟token获取接口
  rest.post("/token", (req, res, ctx) => {
    return res(ctx.text("mock-security-token")); // 返回模拟的token
  })
);

before(() => server.listen());
afterEach(() => server.resetHandlers());
after(() => server.close());

补充说明

如果environment.url.case是相对路径,需在测试环境中配置为绝对路径,或直接在MSW中写死绝对URL(如https://test-api.com/case/api/case/:caseId)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:43:30