ajprs28
ajprs28

Reputation: 63

How to test error get api request react query useInfiniteQuery with react testing library and jest?

I have a function component that used react query useInfiniteQuery to get list data, now I try to test the useInfiniteQuery with error test case get API but still did not cover the onError object function. Does anyone know how to reach onError test with RTL and jest?

useFetchListUsers.ts

export const useFetchListUsers = (params) => {        
    const { users,
        error,
        isLoading,
        isFetching,
        fetchNextPage,
        hasNextPage } = useInfiniteQuery(['users', ...params], getAllUsers, {
            getNextPageParam: (lastPage) => {                            
                return ...lastPage;
            },
            onError: (error: AxiosError) => {
                return "Error get data Users from API"
            },
        });
    
    return { users, error, isLoading, isFetching, fetchNextPage, hasNextPage }
}

usersAPI.ts

export const getAllUsers = async () => {
   const {data} = await axios.get('/v1/users');
   return data;
}

displayUsers.test.tsx

describe('test display list users', () => {
      it("should handle failed get list users", () => {
        (useFetchListUsers as any).mockRejectedValueOnce({
            users: undefined,
        });
    
            render(
                <QueryClientProvider client={queryClient}>
                    <ListUSers />
                </QueryClientProvider>,
                { store }
            );
            expect(await screen.findByTestId("noUsersAlert")).toBeTruthy();
      })
    })

Upvotes: 2

Views: 3878

Answers (1)

TkDodo
TkDodo

Reputation: 28753

if you mock the whole useFetchListUsers function, you cannot expect the onError callback defined inside of that function to be called, because you have mocked said function :)

Further, the onError callback is a callback to execute side-effects; things returned from that function have no meaning. In fact, the signature of onError is: (err: TError) => void, so it doesn't return anything.

I always advice to stub out the network layer with things like mock-service-worker instead of mocking complete hooks. This will ensure your tests are as close as possible to the real application.

If your queryFn returns a rejected Promise, the error property should be filled with that Error. If your UI reads the error property, you don't need onError at all - as I said, it's only for side effects.

In that case, making your mock so that it actually returns an error next to users: undefined might also do the trick.

Upvotes: 2

Related Questions