Skip to content

Commit 7a77af9

Browse files
committed
test(solid-query): use fake timers for useMutation.test.tsx
1 parent e786913 commit 7a77af9

File tree

1 file changed

+67
-67
lines changed

1 file changed

+67
-67
lines changed

packages/solid-query/src/__tests__/useMutation.test.tsx

+67-67
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { describe, expect, it, vi } from 'vitest'
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
22
import {
33
ErrorBoundary,
44
createEffect,
55
createRenderEffect,
66
createSignal,
77
} from 'solid-js'
8-
import { fireEvent, render, waitFor } from '@solidjs/testing-library'
8+
import { fireEvent, render } from '@solidjs/testing-library'
99
import { MutationCache, QueryCache, QueryClientProvider, useMutation } from '..'
1010
import {
1111
createQueryClient,
@@ -17,6 +17,14 @@ import {
1717
import type { UseMutationResult } from '../types'
1818

1919
describe('useMutation', () => {
20+
beforeEach(() => {
21+
vi.useFakeTimers()
22+
})
23+
24+
afterEach(() => {
25+
vi.useRealTimers()
26+
})
27+
2028
const queryCache = new QueryCache()
2129
const mutationCache = new MutationCache()
2230
const queryClient = createQueryClient({ queryCache, mutationCache })
@@ -46,15 +54,14 @@ describe('useMutation', () => {
4654

4755
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
4856

49-
await waitFor(() => {
57+
await vi.waitFor(() => {
5058
expect(rendered.getByRole('heading').textContent).toBe('mutation')
5159
})
5260

5361
fireEvent.click(rendered.getByRole('button', { name: /reset/i }))
5462

55-
await waitFor(() => {
56-
expect(rendered.getByRole('heading').textContent).toBe('empty')
57-
})
63+
await vi.waitFor(() => {})
64+
expect(rendered.getByRole('heading').textContent).toBe('empty')
5865
})
5966

6067
it('should be able to reset `error`', async () => {
@@ -86,21 +93,19 @@ describe('useMutation', () => {
8693
</QueryClientProvider>
8794
))
8895

89-
await waitFor(() => {
90-
expect(rendered.queryByRole('heading')).toBeNull()
91-
})
96+
expect(rendered.queryByRole('heading')).toBeNull()
9297

9398
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
9499

95-
await waitFor(() => {
100+
await vi.waitFor(() => {
96101
expect(rendered.getByRole('heading').textContent).toBe(
97102
'Expected mock error. All is well!',
98103
)
99104
})
100105

101106
fireEvent.click(rendered.getByRole('button', { name: /reset/i }))
102107

103-
await waitFor(() => {
108+
await vi.waitFor(() => {
104109
expect(rendered.queryByRole('heading')).toBeNull()
105110
})
106111

@@ -150,19 +155,19 @@ describe('useMutation', () => {
150155
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
151156
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
152157

153-
await waitFor(() => {
158+
await vi.waitFor(() => {
154159
expect(rendered.getByRole('heading').textContent).toBe('3')
155160
})
156161

157-
await waitFor(() => {
162+
await vi.waitFor(() => {
158163
expect(onSuccessMock).toHaveBeenCalledTimes(3)
159164
})
160165

161166
expect(onSuccessMock).toHaveBeenCalledWith(1)
162167
expect(onSuccessMock).toHaveBeenCalledWith(2)
163168
expect(onSuccessMock).toHaveBeenCalledWith(3)
164169

165-
await waitFor(() => {
170+
await vi.waitFor(() => {
166171
expect(onSettledMock).toHaveBeenCalledTimes(3)
167172
})
168173

@@ -177,14 +182,11 @@ describe('useMutation', () => {
177182

178183
const mutateFn = vi.fn<(value: Value) => Promise<Value>>()
179184

180-
mutateFn.mockImplementationOnce(() => {
181-
return Promise.reject(new Error('Error test Jonas'))
182-
})
185+
mutateFn.mockImplementationOnce(() =>
186+
Promise.reject(new Error('Error test Jonas')),
187+
)
183188

184-
mutateFn.mockImplementation(async (value) => {
185-
await sleep(10)
186-
return Promise.resolve(value)
187-
})
189+
mutateFn.mockImplementation((value) => sleep(10).then(() => value))
188190

189191
function Page() {
190192
const mutation = useMutation(() => ({
@@ -215,20 +217,22 @@ describe('useMutation', () => {
215217
</QueryClientProvider>
216218
))
217219

218-
await waitFor(() => rendered.getByText('Data'))
220+
rendered.getByText('Data')
219221

220222
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
221-
await waitFor(() => rendered.getByText('Data'))
222-
await waitFor(() => rendered.getByText('Status error'))
223-
await waitFor(() => rendered.getByText('Failed 1 times'))
224-
await waitFor(() => rendered.getByText('Failed because Error test Jonas'))
223+
rendered.getByText('Data')
224+
await vi.waitFor(() => rendered.getByText('Status error'))
225+
await vi.waitFor(() => rendered.getByText('Failed 1 times'))
226+
await vi.waitFor(() =>
227+
rendered.getByText('Failed because Error test Jonas'),
228+
)
225229

226230
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
227-
await waitFor(() => rendered.getByText('Status pending'))
228-
await waitFor(() => rendered.getByText('Status success'))
229-
await waitFor(() => rendered.getByText('Data 2'))
230-
await waitFor(() => rendered.getByText('Failed 0 times'))
231-
await waitFor(() => rendered.getByText('Failed because null'))
231+
await vi.waitFor(() => rendered.getByText('Status pending'))
232+
await vi.waitFor(() => rendered.getByText('Status success'))
233+
await vi.waitFor(() => rendered.getByText('Data 2'))
234+
await vi.waitFor(() => rendered.getByText('Failed 0 times'))
235+
await vi.waitFor(() => rendered.getByText('Failed because null'))
232236
})
233237

234238
it('should be able to call `onError` and `onSettled` after each failed mutate', async () => {
@@ -280,11 +284,11 @@ describe('useMutation', () => {
280284
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
281285
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
282286

283-
await waitFor(() => {
287+
await vi.waitFor(() => {
284288
expect(rendered.getByRole('heading').textContent).toBe('3')
285289
})
286290

287-
await waitFor(() => {
291+
await vi.waitFor(() => {
288292
expect(onErrorMock).toHaveBeenCalledTimes(3)
289293
})
290294
expect(onErrorMock).toHaveBeenCalledWith(
@@ -297,7 +301,7 @@ describe('useMutation', () => {
297301
'Expected mock error. All is well! 3',
298302
)
299303

300-
await waitFor(() => {
304+
await vi.waitFor(() => {
301305
expect(onSettledMock).toHaveBeenCalledTimes(3)
302306
})
303307
expect(onSettledMock).toHaveBeenCalledWith(
@@ -351,7 +355,7 @@ describe('useMutation', () => {
351355
</QueryClientProvider>
352356
))
353357

354-
await sleep(100)
358+
await vi.advanceTimersByTimeAsync(10)
355359

356360
expect(callbacks).toEqual([
357361
'useMutation.onSuccess',
@@ -367,7 +371,7 @@ describe('useMutation', () => {
367371

368372
function Page() {
369373
const mutation = useMutation(() => ({
370-
mutationFn: async (_text: string) => Promise.reject(new Error('oops')),
374+
mutationFn: (_text: string) => Promise.reject(new Error('oops')),
371375

372376
onError: () => {
373377
callbacks.push('useMutation.onError')
@@ -404,7 +408,7 @@ describe('useMutation', () => {
404408
</QueryClientProvider>
405409
))
406410

407-
await sleep(100)
411+
await vi.advanceTimersByTimeAsync(10)
408412

409413
expect(callbacks).toEqual([
410414
'useMutation.onError',
@@ -419,10 +423,7 @@ describe('useMutation', () => {
419423
const key = queryKey()
420424

421425
queryClient.setMutationDefaults(key, {
422-
mutationFn: async (text: string) => {
423-
await sleep(10)
424-
return text
425-
},
426+
mutationFn: (text: string) => sleep(10).then(() => text),
426427
})
427428

428429
const states: Array<UseMutationResult<any, any, any, any>> = []
@@ -452,7 +453,7 @@ describe('useMutation', () => {
452453
</QueryClientProvider>
453454
))
454455

455-
await sleep(100)
456+
await vi.advanceTimersByTimeAsync(20)
456457

457458
expect(states.length).toBe(3)
458459
expect(states[0]).toMatchObject({ data: undefined, isPending: false })
@@ -489,7 +490,7 @@ describe('useMutation', () => {
489490
</QueryClientProvider>
490491
))
491492

492-
await sleep(100)
493+
await vi.advanceTimersByTimeAsync(20)
493494

494495
expect(count).toBe(2)
495496
})
@@ -529,34 +530,27 @@ describe('useMutation', () => {
529530
</QueryClientProvider>
530531
))
531532

532-
await waitFor(() => {
533-
expect(
534-
rendered.getByText('error: null, status: idle, isPaused: false'),
535-
).toBeInTheDocument()
536-
})
533+
expect(
534+
rendered.getByText('error: null, status: idle, isPaused: false'),
535+
).toBeInTheDocument()
537536

538537
window.dispatchEvent(new Event('offline'))
539538

540539
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
541540

542-
await waitFor(() => {
543-
expect(
544-
rendered.getByText('error: null, status: pending, isPaused: true'),
545-
).toBeInTheDocument()
546-
})
541+
expect(
542+
rendered.getByText('error: null, status: pending, isPaused: true'),
543+
).toBeInTheDocument()
547544

548545
expect(count).toBe(0)
549546

550547
onlineMock.mockRestore()
551548
window.dispatchEvent(new Event('online'))
552549

553-
await sleep(100)
554-
555-
await waitFor(() => {
556-
expect(
557-
rendered.getByText('error: oops, status: error, isPaused: false'),
558-
).toBeInTheDocument()
559-
})
550+
await vi.advanceTimersByTimeAsync(5)
551+
expect(
552+
rendered.getByText('error: oops, status: error, isPaused: false'),
553+
).toBeInTheDocument()
560554

561555
expect(count).toBe(2)
562556
})
@@ -607,6 +601,7 @@ describe('useMutation', () => {
607601
onlineMock.mockRestore()
608602
window.dispatchEvent(new Event('online'))
609603

604+
await vi.advanceTimersByTimeAsync(10)
610605
await rendered.findByText('data: 1, status: success, isPaused: false')
611606

612607
expect(onMutate).toHaveBeenCalledTimes(1)
@@ -661,6 +656,7 @@ describe('useMutation', () => {
661656
onlineMock.mockReturnValue(true)
662657
window.dispatchEvent(new Event('online'))
663658

659+
await vi.advanceTimersByTimeAsync(10)
664660
await rendered.findByText('data: 1, status: success, isPaused: false')
665661

666662
onlineMock.mockRestore()
@@ -707,7 +703,7 @@ describe('useMutation', () => {
707703
</QueryClientProvider>
708704
))
709705

710-
await sleep(50)
706+
await vi.advanceTimersByTimeAsync(16)
711707

712708
expect(states.length).toBe(4)
713709
expect(states[0]).toMatchObject({
@@ -738,7 +734,7 @@ describe('useMutation', () => {
738734
onlineMock.mockRestore()
739735
window.dispatchEvent(new Event('online'))
740736

741-
await sleep(50)
737+
await vi.advanceTimersByTimeAsync(1)
742738

743739
expect(states.length).toBe(6)
744740
expect(states[4]).toMatchObject({
@@ -818,7 +814,7 @@ describe('useMutation', () => {
818814

819815
fireEvent.click(rendered.getByText('mutate'))
820816

821-
await waitFor(() => {
817+
await vi.waitFor(() => {
822818
expect(rendered.queryByText('error')).not.toBeNull()
823819
})
824820

@@ -868,13 +864,13 @@ describe('useMutation', () => {
868864

869865
// first error goes to component
870866
fireEvent.click(rendered.getByText('mutate'))
871-
await waitFor(() => {
867+
await vi.waitFor(() => {
872868
expect(rendered.queryByText('mock error')).not.toBeNull()
873869
})
874870

875871
// second error goes to boundary
876872
fireEvent.click(rendered.getByText('mutate'))
877-
await waitFor(() => {
873+
await vi.waitFor(() => {
878874
expect(rendered.queryByText('error boundary')).not.toBeNull()
879875
})
880876

@@ -930,7 +926,7 @@ describe('useMutation', () => {
930926
fireEvent.click(rendered.getByText('succeed'))
931927
fireEvent.click(rendered.getByText('error'))
932928

933-
await waitFor(() => {
929+
await vi.waitFor(() => {
934930
expect(rendered.queryByText('successTest')).not.toBeNull()
935931
expect(rendered.queryByText('errorTest')).not.toBeNull()
936932
})
@@ -1003,7 +999,7 @@ describe('useMutation', () => {
1003999
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
10041000
fireEvent.click(rendered.getByRole('button', { name: /hide/i }))
10051001

1006-
await waitFor(() => {
1002+
await vi.waitFor(() => {
10071003
expect(
10081004
queryClient.getMutationCache().findAll({ mutationKey: mutationKey }),
10091005
).toHaveLength(0)
@@ -1065,6 +1061,7 @@ describe('useMutation', () => {
10651061
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
10661062
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
10671063

1064+
await vi.advanceTimersByTimeAsync(10)
10681065
await rendered.findByText('data: result2, status: success')
10691066

10701067
expect(count).toBe(2)
@@ -1114,6 +1111,7 @@ describe('useMutation', () => {
11141111

11151112
rendered.getByRole('button', { name: /mutate/i }).click()
11161113

1114+
await vi.advanceTimersByTimeAsync(10)
11171115
await rendered.findByText('status: error')
11181116

11191117
expect(onError).toHaveBeenCalledWith(error, 'todo', undefined)
@@ -1154,6 +1152,7 @@ describe('useMutation', () => {
11541152

11551153
rendered.getByRole('button', { name: /mutate/i }).click()
11561154

1155+
await vi.advanceTimersByTimeAsync(10)
11571156
await rendered.findByText('error: mutateFnError, status: error')
11581157
})
11591158

@@ -1194,6 +1193,7 @@ describe('useMutation', () => {
11941193

11951194
rendered.getByRole('button', { name: /mutate/i }).click()
11961195

1196+
await vi.advanceTimersByTimeAsync(10)
11971197
await rendered.findByText('error: mutateFnError, status: error')
11981198

11991199
expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined)

0 commit comments

Comments
 (0)