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

传递用户数据时Thunks API测试报错的解决方法

问题描述

调用dataAPI(userSession)传入用户会话时触发报错,不传入参数时API可正常运行,但业务需要动态向API传递Bearer Token,求解决办法。

测试代码

it("should call get the data centers' API correctly and get correct values", async () => {
  const getSpy = jest.spyOn(dataAPI(userSession), "get").mockResolvedValueOnce({
    data: dataCenters,
  });

  await mockedStore.dispatch(getDataCenters());
  expect(getSpy).toBeCalled();
  expect(getSpy).toBeCalledWith(`DataCenters/GetDataCenters`);
  const state = mockedStore.getState();
  expect(state.dataCenter.dataCenters).toEqual(dataCenters);
});

export const userSession = {
  sessionId: "123RalIh1QCvPYtNi5hs",
  bearerToken: "abcdKQmBWheOqLdxa4H50HiPii6kcwK64"
}

Thunks API代码

export const getDataCenters = createAsyncThunk(
  "data-centers/getDataCenters",
  async (requestData, { getState, dispatch }) => {
    try {
      dispatch(setLoading(true));
      const user = JSON.parse(String(sessionStorage.getItem("user")));
      const result = await dataAPI(user).get(`DataCenters/GetDataCenters`);
      dispatch(setLoading(false));
      return result.data;
    } catch (error: any) {
      dispatch(setLoading(false));
      throw error;
    }
  }
);

export const dataAPI = (user: any) => {
  return axios.create({
    baseURL: apiUrl,
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${user.bearerToken}`
    },
  });
}

错误信息

TypeError: Cannot read properties of null (reading 'bearerToken')


解决方案

问题根源

测试执行时,sessionStorage.getItem("user")返回null,JSON.parse后得到null,调用dataAPI(null)时访问user.bearerToken触发空指针错误;同时测试代码直接调用dataAPI(userSession)创建实例,但Thunk逻辑是从sessionStorage取用户,两者数据源不一致。

修复步骤

  1. 给Thunk添加空值校验
    在调用dataAPI前先判断用户是否存在,避免空指针:

    export const getDataCenters = createAsyncThunk(
      "data-centers/getDataCenters",
      async (requestData, { getState, dispatch }) => {
        try {
          dispatch(setLoading(true));
          const userStr = sessionStorage.getItem("user");
          if (!userStr) {
            throw new Error("用户未登录");
          }
          const user = JSON.parse(userStr);
          const result = await dataAPI(user).get(`DataCenters/GetDataCenters`);
          dispatch(setLoading(false));
          return result.data;
        } catch (error: any) {
          dispatch(setLoading(false));
          throw error;
        }
      }
    );
    
  2. 测试代码中模拟sessionStorage数据
    测试前给sessionStorage设置用户数据,保证Thunk能正确获取到用户:

    it("should call get the data centers' API correctly and get correct values", async () => {
      // 模拟sessionStorage中的用户数据
      sessionStorage.setItem("user", JSON.stringify(userSession));
      
      // 复用同一个API实例,避免spyOn失效
      const apiInstance = dataAPI(userSession);
      const getSpy = jest.spyOn(apiInstance, "get").mockResolvedValueOnce({
        data: dataCenters,
      });
    
      await mockedStore.dispatch(getDataCenters());
      expect(getSpy).toBeCalled();
      expect(getSpy).toBeCalledWith(`DataCenters/GetDataCenters`);
      const state = mockedStore.getState();
      expect(state.dataCenter.dataCenters).toEqual(dataCenters);
      
      // 测试后清理sessionStorage
      sessionStorage.removeItem("user");
    });
    
  3. 给dataAPI添加参数校验
    提前拦截无效用户输入,明确报错原因:

    export const dataAPI = (user: any) => {
      if (!user?.bearerToken) {
        throw new Error("缺少有效的Bearer Token");
      }
      return axios.create({
        baseURL: apiUrl,
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${user.bearerToken}`
        },
      });
    }
    

内容的提问来源于stack exchange,提问作者Arun Kumar M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:33:28