From 41a7ab07e7d46d9ce685ccd5008e769cef23d075 Mon Sep 17 00:00:00 2001 From: palkim Date: Fri, 24 Apr 2026 16:32:44 +0900 Subject: [PATCH] test(query-core/utils): add tests for 'ensureQueryFn' with 'initialPromise' and 'skipToken' (#10527) * test(query-core/utils): add tests for 'ensureQueryFn' initialPromise fallback and skipToken handling * test(query-core/utils): use typed QueryFunctionContext in ensureQueryFn tests Replace the `(resolved as unknown as () => Promise<...>)()` double-cast with `resolved(context)` using a shared `QueryFunctionContext` fixture. Per review suggestions on #10527. --------- Co-authored-by: Wonsuk Choi --- .../query-core/src/__tests__/utils.test.tsx | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/packages/query-core/src/__tests__/utils.test.tsx b/packages/query-core/src/__tests__/utils.test.tsx index f9b0ee4fa07..69c72a50aa8 100644 --- a/packages/query-core/src/__tests__/utils.test.tsx +++ b/packages/query-core/src/__tests__/utils.test.tsx @@ -4,6 +4,7 @@ import { QueryClient } from '..' import { addToEnd, addToStart, + ensureQueryFn, hashKey, hashQueryKeyByOptions, isPlainArray, @@ -14,8 +15,10 @@ import { replaceEqualDeep, shallowEqualObjects, shouldThrowError, + skipToken, } from '../utils' import { Mutation } from '../mutation' +import type { QueryFunctionContext } from '..' describe('core/utils', () => { describe('hashQueryKeyByOptions', () => { @@ -534,6 +537,55 @@ describe('core/utils', () => { }) }) + describe('ensureQueryFn', () => { + const context = {} as QueryFunctionContext + + it('should return a function that resolves to initialPromise when queryFn is missing and initialPromise is provided', async () => { + const initialPromise = Promise.resolve('initial-data') + + const resolved = ensureQueryFn( + { queryHash: '["key"]' }, + { initialPromise }, + ) + + await expect(resolved(context)).resolves.toBe('initial-data') + }) + + it('should return a function that rejects when initialPromise rejects', async () => { + const error = new Error('initial-promise-error') + const initialPromise = Promise.reject(error) + + const resolved = ensureQueryFn( + { queryHash: '["key"]' }, + { initialPromise }, + ) + + await expect(resolved(context)).rejects.toBe(error) + }) + + it('should return a function that rejects with missing queryFn error when queryFn is set to skipToken', async () => { + const consoleErrorSpy = vi + .spyOn(console, 'error') + .mockImplementation(() => undefined) + + const resolved = ensureQueryFn({ + queryFn: skipToken, + queryHash: '["skip"]', + }) + + expect(consoleErrorSpy).toHaveBeenCalledWith( + expect.stringContaining( + 'Attempted to invoke queryFn when set to skipToken', + ), + ) + await expect(resolved(context)).rejects.toThrow( + 'Missing queryFn: \'["skip"]\'', + ) + + consoleErrorSpy.mockRestore() + }) + }) + describe('shouldThrowError', () => { it('should return the result of executing throwOnError if throwOnError parameter is a function', () => { const throwOnError = (error: Error) => error.message === 'test error'