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

使用Jest测试RTK Query时token放查询参数认证失败如何解决?

问题根因

你的核心问题出在token的获取时机:

  • 你在dataEndpoint.ts模块顶层调用getToken(),模块加载时就会执行这行代码拿到固定的token值,而测试环境下模块加载时localStorage里还没有设置有效token,最终发起请求时token参数为空/无效,触发401。
  • 另外你的测试代码里存在几处拼写错误也会导致执行异常:cosnt应为const、waitForNextupdate应为waitForNextUpdate、JSON.string应为JSON.stringify。
修复步骤
  1. 调整端点定义逻辑,将token获取移到query函数内部,每次请求发起时动态读取,避免模块加载时固定死token值
  2. 测试前置操作中往localStorage写入有效测试token
  3. 可选:配置fetchMock校验请求token参数,符合预期才返回成功响应
修改后的代码示例

端点代码(dataEndpoint.ts)

// 删掉模块级的token声明,移到query内部动态获取
export const apiWithData = rootApi.injectEndpoints({
  endpoints: (build) => ({
    fetchDataMetaList: build.mutation<DataType, any>({
      query: ({offset = 0, size = 20, body}) => {
        const token = getToken(); // 每次发起请求时动态读token
        return {
          url: `${API_URL}?offset=${offset}&size=${size}&token=${token}`,
          method: "POST",
          body: body || {}
        }
      }
    })
  })
})

测试代码(data.test.tsx)

const body = { offset: 0, size: 20, body: {} };
const updateTimeout = 10000;
const TEST_TOKEN = 'test_valid_token_123'; // 测试用有效token
// 替换为你getToken方法里读取的localStorage key
const TOKEN_STORAGE_KEY = 'user_token';

beforeEach((): void => {
  fetchMock.resetMocks();
  // 测试前置写入有效token到localStorage
  localStorage.setItem(TOKEN_STORAGE_KEY, TEST_TOKEN);
})

const wrapper: React.FC = ({ children }) => {
  const storeRef = setupApiStore(rootApi);
  return <Provider store={storeRef.store}>{children}</Provider>
}

describe("useFetchDataMetaListMutation", () => {
  it("Success", async () => {
    // 配置mock校验token参数
    fetchMock.mockIf(new RegExp(`${API_URL}.*`), async (req) => {
      const reqUrl = new URL(req.url);
      if (reqUrl.searchParams.get('token') === TEST_TOKEN) {
        // token匹配返回成功响应
        return {
          status: 200,
          body: JSON.stringify(response) // 替换为你的mock返回值
        }
      }
      // token不匹配返回401
      return {
        status: 401,
        body: JSON.stringify({msg: 'Unauthorized'})
      }
    })

    const { result, waitForNextUpdate } = renderHook(
      () => useFetchDataMetaListMutation(), 
      { wrapper }
    )

    const [fetchDataMetaList, initialResponse] = result.current;
    expect(initialResponse.data).toBeUndefined();
    expect(initialResponse.isLoading).toBe(false);

    act(() => {
      void fetchDataMetaList(body);
    })

    const loadingResponse = result.current[1];
    expect(loadingResponse.data).toBeUndefined();
    expect(loadingResponse.isLoading).toBe(true);

    await waitForNextUpdate({ timeout: updateTimeout });

    const loadedResponse = result.current[1];
    expect(loadedResponse.isSuccess).toBe(true);
    expect(loadedResponse.data).toBeDefined();
  })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:06:04