querycache not being updated by setQueryData when testing custom hook #4036
-
I'm new to testing and have been unable to resolve what I thought was a simple test case on a custom hook that uses React query useQuery and setQueryData . Any help on this would be greatly appreciated. I've had no luck solving this for a couple of days and I'm at a loss... "dependencies": { I have a custom hook: function useGlobalState(key, initialData) {
const { data, isFetching, isSuccess, refetch, isIdle, isLoading } = useQuery(
key,
() => initialData,
{
enabled: false,
initialData,
onSuccess: (data) => {
console.log("Get data!");
console.log(key, data);
console.log(queryClient);
},
}
);
return [
data,
(value) => queryClient.setQueryData(key, value),
{ isFetching, isSuccess, refetch, isIdle, isLoading },
];
} I'm using this in a basic weather app to store latitude, longitude, and place names for forecasts and just call invalidateQueries() on some other hooks to get new forecast data. Setup is something like: const [data, setData] = useGlobalState("weatherConfig", {
name: "forecast location",
coordinates: {
lat: 50,
long: -10
}); My problem is that I have been unable to get the setData() working in my tests. I works fine in production: import { QueryClientProvider, QueryClient } from "react-query";
import {
renderHook,
waitFor,
act,
render,
screen,
} from "@testing-library/react";
import useGlobalState from "../useGlobalState";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
persist: true,
notifyOnChangeProps: "all",
},
});
const wrapper = ({ children }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
const TestComponent = ({ data }) => {
return <p>{data}</p>;
};
describe("useGlobalState Hook", () => {
const initialData = {
testKey: "this is some data",
};
it("should set new data", async () => {
const { result, unmount, rerender } = renderHook(
() => useGlobalState("isolatedTestingQuery", "isFirstValue"),
{
wrapper,
}
);
const [data, setData, status] = result.current;
const { isFetching, isSuccess, refetch, isIdle, isLoading } = status;
render(
<QueryClientProvider client={queryClient}>
<TestComponent data={data} />
</QueryClientProvider>
);
const value = "the data has been changed";
const defaultTestEl = screen.getByText(/isFirstValue/i);
expect(defaultTestEl).toBeInTheDocument();
// Neither of the below attempts to update data with setData does anything
/setData(value);
act(() => {
return setData(value);
});
render(
<QueryClientProvider client={queryClient}>
<TestComponent data={data} />
</QueryClientProvider>
);
const changedtTestEl = screen.getByText(/the data has been changed/i);
expect(changedtTestEl).toBeInTheDocument();
});
}); Final test results are always: Ignored nodes: comments, <script />, <style />
<body>
<div />
<div>
<p>
isFirstValue
</p>
</div>
<div>
<p>
isFirstValue
</p>
</div>
</body>
81 | </QueryClientProvider>
82 | );
> 83 | const changedtTestEl = screen.getByText(/the data has been changed/i); Edit: This code passes tests while giving an act error act(() => queryClient.setQueryData("isolatedTestingQuery", value));
render(
<QueryClientProvider client={queryClient}>
<TestComponent
data={queryClient.getQueryData("isolatedTestingQuery")}
/>
</QueryClientProvider>
); |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Make the test component render a button with an onClick handler that calls setQueryData. Then, interact with the button and click it via testing-library:
|
Beta Was this translation helpful? Give feedback.
Make the test component render a button with an onClick handler that calls setQueryData. Then, interact with the button and click it via testing-library: