T
TanStack•4y ago
rival-black

Testing optimistic update in react query.

I am trying to write test case for optimistic update mutation. But it's not workin for some reason. Can anyone please have a look here. I am providing the stack overflow link. https://stackoverflow.com/questions/74209718/testing-optimistic-update-in-react-query
Stack Overflow
Testing Optimistic update in react query
I am trying to write the test case for an optimistic update in react query. But it's not working. Here is the code that I wrote to test it. Hope someone could help me. Thanks in advance. When I just
9 Replies
rival-black
rival-blackOP•4y ago
It's getting to onError due to this line const previousColorData = queryClient.getQueryData(['colors', page]) Maybe i need to mock this getQueryData but don't know how to do that
adverse-sapphire
adverse-sapphire•4y ago
answered
rival-black
rival-blackOP•4y ago
Thanks but I have one more query. Can we somehow, mimic the cached data for a specific key and get the oldQueryData? I was able to get the previousData by mocking it but the other methods are not working well. Suppose I just want to mock getQueryData for a particular test case and leave the other functions like invalidateQueries, cancelQuery, and setQueryData, as it is, then how, can modify this mock function? This is what I wrote. But getting this
TypeError: queryClient.cancelQueries is not a function
TypeError: queryClient.cancelQueries is not a function
jest.mock("@tanstack/react-query", () => ({
...jest.requireActual("@tanstack/react-query"),
useQueryClient: () => ({
// setQueryData: jest.fn(() => ({ data: [{ label: 'Blue', id: 34 }] })),
// cancelQueries: jest.fn(),
// invalidateQueries: jest.fn(),
...jest.requireActual("@tanstack/react-query").useQueryClient(),
getQueryData: jest
.fn()
.mockReturnValueOnce({ data: [{ id: 1, quantity: 1 }] })
.mockReturnValueOnce({ data: [{ id: 1, quantity: 2 }] }),
}),
}));
jest.mock("@tanstack/react-query", () => ({
...jest.requireActual("@tanstack/react-query"),
useQueryClient: () => ({
// setQueryData: jest.fn(() => ({ data: [{ label: 'Blue', id: 34 }] })),
// cancelQueries: jest.fn(),
// invalidateQueries: jest.fn(),
...jest.requireActual("@tanstack/react-query").useQueryClient(),
getQueryData: jest
.fn()
.mockReturnValueOnce({ data: [{ id: 1, quantity: 1 }] })
.mockReturnValueOnce({ data: [{ id: 1, quantity: 2 }] }),
}),
}));
adverse-sapphire
adverse-sapphire•4y ago
if you just put data in your cache with queryClient.setQueryData for the right key in your test (just after the creation of the queryClient), it will be returned from getQueryData. I wouldn't mock anything except the network itself 🙂
rival-black
rival-blackOP•4y ago
I tried that as well. But got some error.
import { useQueryClient } from "@tanstack/react-query";
import { act, renderHook } from "@testing-library/react-hooks";
import axios from "axios";
import { createWrapper } from "../../test-utils";
import { useAddColorHook, useFetchColorHook } from "./usePaginationReactQuery";
jest.mock("axios");

describe('Testing custom hooks of react query', () => {
const queryClient = useQueryClient()
it('Should add a new color', async () => {
queryClient.setQueryData(['colors', 1], { data: [{ id: 1, quantity: 1 }] })
axios.post.mockReturnValue({ data: [{ label: 'Grey', id: 23 }] })
const { result, waitFor } = renderHook(() => useAddColorHook(1), { wrapper: createWrapper() });
await act(() => {
result.current.mutate({ label: 'Grey' })
})
await waitFor(() => result.current.isSuccess);
})

it('Should handle errors while adding color', async () => {
axios.post.mockRejectedValueOnce()
const { result, waitFor } = renderHook(() => useAddColorHook(1), { wrapper: createWrapper() });
await act(() => {
result.current.mutate({ label: 'Grey' })
})
await waitFor(() => result.current.isError);
})
})
import { useQueryClient } from "@tanstack/react-query";
import { act, renderHook } from "@testing-library/react-hooks";
import axios from "axios";
import { createWrapper } from "../../test-utils";
import { useAddColorHook, useFetchColorHook } from "./usePaginationReactQuery";
jest.mock("axios");

describe('Testing custom hooks of react query', () => {
const queryClient = useQueryClient()
it('Should add a new color', async () => {
queryClient.setQueryData(['colors', 1], { data: [{ id: 1, quantity: 1 }] })
axios.post.mockReturnValue({ data: [{ label: 'Grey', id: 23 }] })
const { result, waitFor } = renderHook(() => useAddColorHook(1), { wrapper: createWrapper() });
await act(() => {
result.current.mutate({ label: 'Grey' })
})
await waitFor(() => result.current.isSuccess);
})

it('Should handle errors while adding color', async () => {
axios.post.mockRejectedValueOnce()
const { result, waitFor } = renderHook(() => useAddColorHook(1), { wrapper: createWrapper() });
await act(() => {
result.current.mutate({ label: 'Grey' })
})
await waitFor(() => result.current.isError);
})
})
TypeError: Cannot read property 'useContext' of null 7 | 8 | describe('Testing custom hooks of react query', () => {
9 | const queryClient = useQueryClient()
Sorry for the constant message but I really am stuck with the test case. If you please tell me what wrong am I doing here. I tried all the possible appraoch.
adverse-sapphire
adverse-sapphire•4y ago
You can't useQueryClient outside of react components.... Do the seeding right in the wrapper where you create the client and have access to it
rival-black
rival-blackOP•4y ago
I have followed your approach for testing. Don't know how can I modify the wrapper to fit my condition. Below is the code for wrapper. Can you make the changes here as per my requirement.
export const createTestQueryClient = () =>
new QueryClient({
defaultOptions: {
queries: {
retry: false,
cacheTime: Infinity,
},
},
logger: {
log: console.log,
warn: console.warn,
error: () => {},
}
});

export function createWrapper() {
const testQueryClient = createTestQueryClient();
return ({ children }) => (
<QueryClientProvider client={testQueryClient}>
{children}
</QueryClientProvider>
);
}
export const createTestQueryClient = () =>
new QueryClient({
defaultOptions: {
queries: {
retry: false,
cacheTime: Infinity,
},
},
logger: {
log: console.log,
warn: console.warn,
error: () => {},
}
});

export function createWrapper() {
const testQueryClient = createTestQueryClient();
return ({ children }) => (
<QueryClientProvider client={testQueryClient}>
{children}
</QueryClientProvider>
);
}
adverse-sapphire
adverse-sapphire•4y ago
I mean:
export const createTestQueryClient = () => {
const queryClient = new QueryClient(...)
queryClient.setQueryData(...)

return queryClient
}
export const createTestQueryClient = () => {
const queryClient = new QueryClient(...)
queryClient.setQueryData(...)

return queryClient
}
???
rival-black
rival-blackOP•4y ago
Thanks a lot. It finally worked

Did you find this page helpful?