【问题标题】:Testing Redux Toolkit Query using jest issue with auth使用带有 auth 的玩笑问题测试 Redux Toolkit Query
【发布时间】:2021-12-03 00:10:59
【问题描述】:

我目前正在尝试为我的 RTKQuery 编写笑话测试,但我在测试的身份验证级别上卡住了。

基本上,我使用的 api 旨在将令牌放在查询参数上,而不是放在请求标头上:"https://api/v1/something/meta/?token=userToken"

因此,当我尝试测试 api 调用时,它显示请求已被拒绝。有谁知道如何用这种情况编写测试?

这是我的 RTKQuery 端点:

// index.ts
export const rootApi = createApi({
  reducerPath: "root",
  baseQuery: fetchBaseQuery({baseUrl: API_ROOT}),
  endpoints: () => ({});
})

// dataEndpoint.ts
const token = getToken(); // Gets the user's token from localStorage after user login

export cosnt apiWithData = rootApi.injectEndpoints({
  endpoints: (build) => ({
    fetchDataMetaList: build.mutation<DataType, any>({
      query: ({offset = 0, size = 20, body}) => ({
        // token is passed in for query param
        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;

beforeEach((): void => {
  fetchMock.resetMocks();
})

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

describe("useFetchDataMetaListMutation", () => {
  it("Success", async () => {
    fetchMock.mockResponse(JSON.string(response));
    cosnt { 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);

    // Up til this point everything is passing fine
   
    await waitForNextUpdate({ timeout: updateTimeout });

    const loadedResponse = result.current[1];

    // expect loadedResponse.data to be defined, but returned undefined
    // console out put for loaded Response status is 'rejected' with 401 access level 
    // error code
  })
})

【问题讨论】:

    标签: reactjs rtk-query jest-fetch-mock


    【解决方案1】:

    执行顶级const token 意味着一旦加载该文件,它将从本地存储中检索该令牌,并且永远无法更新该令牌 - 因此,如果该文件在用户之前加载已登录,它将为空。这几乎也是您在此处的测试中发生的情况。

    说实话,这可能是我第一次看到令牌作为 url 的一部分(这是一个严重的安全问题,因为令牌将在用户之间共享复制粘贴 url,它在即使在注销等之后浏览器历史记录!)。

    不幸的是,在这种情况下,你不能使用prepareHeaders,但至少你可以代替const,使用一个函数来获取当前的令牌——如果你从另一个文件中导入它,你也可以使用开玩笑的模拟只需关闭该导入即可。

    【讨论】:

    • 感谢您的信息。是的,URL 中的令牌不是一种正确的方法,但是身份验证的改进版本会不断延迟。我目前正在为 FE 开发 UT,这开始成为一个问题。无论如何,您能否在最后一部分中再解释一下,您提到使用函数来获取当前令牌?您的意思是在 .test 文件中获取当前令牌并将其传递给有效负载主体,例如fetchDataMetaList({offset, size, body, token}),我对开玩笑测试还是很陌生,任何详细说明或参考将不胜感激
    • 哦,实际上,我已经想出在每次测试之前设置用户令牌以获取令牌。在我进行手动设置之前,我的令牌是在测试控制台上打印出null。但是现在如果我手动设置它就会打印出令牌
    • 我只是想从token.js 文件中导出getToken 函数并模拟该函数。但是很好,您找到了解决方案:)
    猜你喜欢
    • 2023-02-21
    • 2020-03-25
    • 2023-01-15
    • 2023-01-18
    • 1970-01-01
    • 2018-09-01
    • 2023-02-23
    • 1970-01-01
    • 2022-09-25
    相关资源
    最近更新 更多