Skip to content

Commit 593119b

Browse files
committed
chore: tests for useQuery, useInfiniteQuery, useIsFetching, useQueryClient
1 parent 3b15db1 commit 593119b

File tree

5 files changed

+239
-3
lines changed

5 files changed

+239
-3
lines changed

tests/useInfiniteQuery.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { QueryClient, setLogger } from "react-query/core";
2+
import { useInfiniteQuery } from "../src/useInfiniteQuery";
3+
import { noop, infiniteFetcher, flushPromises } from "./utils";
4+
5+
jest.mock("vue", () => {
6+
const vue = jest.requireActual("vue");
7+
return {
8+
...vue,
9+
onUnmounted: jest.fn(),
10+
};
11+
});
12+
13+
jest.mock("../src/useQueryClient", () => {
14+
const queryClient = new QueryClient();
15+
return {
16+
useQueryClient: jest.fn(() => queryClient),
17+
};
18+
});
19+
20+
jest.mock("../src/useBaseQuery", () => {
21+
const { useBaseQuery: originImpl } = jest.requireActual(
22+
"../src/useBaseQuery"
23+
);
24+
return {
25+
useBaseQuery: jest.fn(originImpl),
26+
};
27+
});
28+
29+
describe("useQuery", () => {
30+
beforeAll(() => {
31+
setLogger({ log: noop, warn: noop, error: noop });
32+
});
33+
34+
beforeEach(() => {
35+
jest.clearAllMocks();
36+
});
37+
38+
test("should properly execute infinite query", async () => {
39+
const { data, fetchNextPage, status } = useInfiniteQuery(
40+
"infiniteQuery",
41+
infiniteFetcher
42+
);
43+
44+
expect(data.value).toStrictEqual(undefined);
45+
expect(status.value).toStrictEqual("loading");
46+
47+
await flushPromises();
48+
49+
expect(data.value).toStrictEqual({
50+
pageParams: [undefined],
51+
pages: ["data on page 0"],
52+
});
53+
expect(status.value).toStrictEqual("success");
54+
55+
fetchNextPage.value({ pageParam: 12 });
56+
57+
await flushPromises();
58+
59+
expect(data.value).toStrictEqual({
60+
pageParams: [undefined, 12],
61+
pages: ["data on page 0", "data on page 12"],
62+
});
63+
expect(status.value).toStrictEqual("success");
64+
});
65+
});

tests/useIsFetching.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { onUnmounted } from "vue";
2+
import { QueryClient, setLogger } from "react-query/core";
3+
import { useQuery } from "../src/useQuery";
4+
import { useIsFetching } from "../src/useIsFetching";
5+
import { flushPromises, simpleFetcher, noop } from "./utils";
6+
7+
jest.mock("vue", () => {
8+
const vue = jest.requireActual("vue");
9+
return {
10+
...vue,
11+
onUnmounted: jest.fn(),
12+
};
13+
});
14+
15+
jest.mock("../src/useQueryClient", () => {
16+
const queryClient = new QueryClient();
17+
return {
18+
useQueryClient: jest.fn(() => queryClient),
19+
};
20+
});
21+
22+
jest.mock("../src/useBaseQuery", () => {
23+
const { useBaseQuery: originImpl } = jest.requireActual(
24+
"../src/useBaseQuery"
25+
);
26+
return {
27+
useBaseQuery: jest.fn(originImpl),
28+
};
29+
});
30+
31+
describe("useIsFetching", () => {
32+
beforeAll(() => {
33+
setLogger({ log: noop, warn: noop, error: noop });
34+
});
35+
36+
beforeEach(() => {
37+
jest.clearAllMocks();
38+
});
39+
40+
test("should properly return isFetching state", async () => {
41+
const { isFetching: isFetchingQuery } = useQuery(
42+
"isFetching1",
43+
simpleFetcher
44+
);
45+
useQuery("isFetching2", simpleFetcher);
46+
const isFetching = useIsFetching();
47+
48+
expect(isFetchingQuery.value).toStrictEqual(true);
49+
expect(isFetching.value).toStrictEqual(2);
50+
51+
await flushPromises();
52+
53+
expect(isFetchingQuery.value).toStrictEqual(false);
54+
expect(isFetching.value).toStrictEqual(0);
55+
});
56+
57+
test("should stop listening to changes on onUnmount", async () => {
58+
const onUnmountedMock = onUnmounted as jest.MockedFunction<
59+
typeof onUnmounted
60+
>;
61+
onUnmountedMock.mockImplementation((fn) => fn());
62+
63+
const { status } = useQuery("onUnmounted", simpleFetcher);
64+
const isFetching = useIsFetching();
65+
66+
expect(status.value).toStrictEqual("loading");
67+
expect(isFetching.value).toStrictEqual(1);
68+
69+
await flushPromises();
70+
71+
expect(status.value).toStrictEqual("loading");
72+
expect(isFetching.value).toStrictEqual(1);
73+
74+
await flushPromises();
75+
76+
expect(status.value).toStrictEqual("loading");
77+
expect(isFetching.value).toStrictEqual(1);
78+
79+
onUnmountedMock.mockReset();
80+
});
81+
});

tests/useBaseQuery.test.ts renamed to tests/useQuery.test.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ref } from "vue";
1+
import { computed, reactive, ref, onUnmounted } from "vue";
22
import { QueryClient, QueryObserver, setLogger } from "react-query/core";
33
import { useQuery } from "../src/useQuery";
44
import { useBaseQuery } from "../src/useBaseQuery";
@@ -8,7 +8,7 @@ jest.mock("vue", () => {
88
const vue = jest.requireActual("vue");
99
return {
1010
...vue,
11-
onUnmounted: jest.fn((fn) => setTimeout(fn, 0)),
11+
onUnmounted: jest.fn(),
1212
};
1313
});
1414

@@ -33,7 +33,7 @@ describe("useQuery", () => {
3333
setLogger({ log: noop, warn: noop, error: noop });
3434
});
3535

36-
afterEach(() => {
36+
beforeEach(() => {
3737
jest.clearAllMocks();
3838
});
3939

@@ -170,4 +170,49 @@ describe("useQuery", () => {
170170

171171
expect(spy).toBeCalledTimes(1);
172172
});
173+
174+
test("should properly execute dependant queries", async () => {
175+
const { data } = useQuery("dependant1", simpleFetcher);
176+
177+
const enabled = computed(() => !!data.value);
178+
179+
const { status } = useQuery(
180+
reactive({
181+
queryKey: "dependant2",
182+
queryFn: simpleFetcher,
183+
enabled,
184+
})
185+
);
186+
187+
expect(data.value).toStrictEqual(undefined);
188+
expect(status.value).toStrictEqual("idle");
189+
190+
await flushPromises();
191+
192+
expect(data.value).toStrictEqual("Some data");
193+
expect(status.value).toStrictEqual("loading");
194+
195+
await flushPromises();
196+
197+
expect(status.value).toStrictEqual("success");
198+
});
199+
200+
test("should stop listening to changes on onUnmount", async () => {
201+
const onUnmountedMock = onUnmounted as jest.MockedFunction<
202+
typeof onUnmounted
203+
>;
204+
onUnmountedMock.mockImplementationOnce((fn) => fn());
205+
206+
const { status } = useQuery("onUnmounted", simpleFetcher);
207+
208+
expect(status.value).toStrictEqual("loading");
209+
210+
await flushPromises();
211+
212+
expect(status.value).toStrictEqual("loading");
213+
214+
await flushPromises();
215+
216+
expect(status.value).toStrictEqual("loading");
217+
});
173218
});

tests/useQueryClient.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as vue from "vue";
2+
import { useQueryClient, VUE_REACT_QUERY_CLIENT } from "../src/useQueryClient";
3+
4+
describe("useQueryClient", () => {
5+
beforeEach(() => {
6+
jest.restoreAllMocks();
7+
});
8+
9+
test("should return queryClient when it is provided in the context", () => {
10+
const queryClientMock = { name: "Mocked client" };
11+
const injectSpy = jest
12+
.spyOn(vue, "inject")
13+
.mockReturnValue(queryClientMock);
14+
15+
const queryClient = useQueryClient();
16+
17+
expect(queryClient).toStrictEqual(queryClientMock);
18+
expect(injectSpy).toHaveBeenCalledTimes(1);
19+
expect(injectSpy).toHaveBeenCalledWith(VUE_REACT_QUERY_CLIENT);
20+
});
21+
22+
test("should throw an error when queryClient does not exist in the context", () => {
23+
const injectSpy = jest.spyOn(vue, "inject").mockReturnValue(undefined);
24+
25+
expect(useQueryClient).toThrowError(
26+
Error(
27+
"No queryClient found in Vue context, use 'app.provide(VUE_REACT_QUERY_CLIENT, new QueryClient());' to set one in root component."
28+
)
29+
);
30+
expect(injectSpy).toHaveBeenCalledTimes(1);
31+
expect(injectSpy).toHaveBeenCalledWith(VUE_REACT_QUERY_CLIENT);
32+
});
33+
});

tests/utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ export function simpleFetcher(): Promise<string> {
1212
});
1313
}
1414

15+
export function infiniteFetcher({
16+
pageParam = 0,
17+
}: {
18+
pageParam?: number;
19+
}): Promise<string> {
20+
return new Promise((resolve) => {
21+
setTimeout(() => {
22+
return resolve("data on page " + pageParam);
23+
}, 0);
24+
});
25+
}
26+
1527
export function rejectFetcher(): Promise<Error> {
1628
return new Promise((resolve, reject) => {
1729
setTimeout(() => {

0 commit comments

Comments
 (0)