@@ -4,7 +4,8 @@ description: Some tips on testing components that use `nuqs`
4
4
---
5
5
6
6
Since nuqs 2, you can unit-test components that use ` useQueryState(s){:ts} ` hooks
7
- by wrapping your rendered component in a ` NuqsTestingAdapter{:ts} ` .
7
+ by wrapping your rendered component in a ` NuqsTestingAdapter{:ts} ` , or using
8
+ the ` withNuqsTestingAdapter{:ts} ` higher-order component.
8
9
9
10
## With Vitest
10
11
@@ -14,10 +15,10 @@ a counter:
14
15
<Tabs items = { [' Vitest v1' , ' Vitest v2' ]} >
15
16
16
17
``` tsx title="counter-button.test.tsx" tab="Vitest v1"
17
- // [!code word:NuqsTestingAdapter ]
18
+ // [!code word:withNuqsTestingAdapter ]
18
19
import { render , screen } from ' @testing-library/react'
19
20
import userEvent from ' @testing-library/user-event'
20
- import { NuqsTestingAdapter , type UrlUpdateEvent } from ' nuqs/adapters/testing'
21
+ import { withNuqsTestingAdapter , type UrlUpdateEvent } from ' nuqs/adapters/testing'
21
22
import { describe , expect , it , vi } from ' vitest'
22
23
import { CounterButton } from ' ./counter-button'
23
24
@@ -26,11 +27,7 @@ it('should increment the count when clicked', async () => {
26
27
const onUrlUpdate = vi .fn <[UrlUpdateEvent ]>()
27
28
render (<CounterButton />, {
28
29
// 1. Setup the test by passing initial search params / querystring:
29
- wrapper : ({ children }) => (
30
- <NuqsTestingAdapter searchParams = " ?count=42" onUrlUpdate = { onUrlUpdate } >
31
- { children }
32
- </NuqsTestingAdapter >
33
- )
30
+ wrapper: withNuqsTestingAdapter ({ searchParams: ' ?count=42' , onUrlUpdate })
34
31
})
35
32
// 2. Act
36
33
const button = screen .getByRole (' button' )
@@ -46,10 +43,10 @@ it('should increment the count when clicked', async () => {
46
43
```
47
44
48
45
``` tsx title="counter-button.test.tsx" tab="Vitest v2"
49
- // [!code word:NuqsTestingAdapter ]
46
+ // [!code word:withNuqsTestingAdapter ]
50
47
import { render , screen } from ' @testing-library/react'
51
48
import userEvent from ' @testing-library/user-event'
52
- import { NuqsTestingAdapter , type OnUrlUpdateFunction } from ' nuqs/adapters/testing'
49
+ import { withNuqsTestingAdapter , type OnUrlUpdateFunction } from ' nuqs/adapters/testing'
53
50
import { describe , expect , it , vi } from ' vitest'
54
51
import { CounterButton } from ' ./counter-button'
55
52
@@ -58,11 +55,7 @@ it('should increment the count when clicked', async () => {
58
55
const onUrlUpdate = vi .fn <OnUrlUpdateFunction >()
59
56
render (<CounterButton />, {
60
57
// 1. Setup the test by passing initial search params / querystring:
61
- wrapper : ({ children }) => (
62
- <NuqsTestingAdapter searchParams = " ?count=42" onUrlUpdate = { onUrlUpdate } >
63
- { children }
64
- </NuqsTestingAdapter >
65
- )
58
+ wrapper: withNuqsTestingAdapter ({ searchParams: ' ?count=42' , onUrlUpdate })
66
59
})
67
60
// 2. Act
68
61
const button = screen .getByRole (' button' )
@@ -112,3 +105,44 @@ const config: Config = {
112
105
<Callout >
113
106
Adapt accordingly for Windows with [ ` cross-env ` ] ( https://www.npmjs.com/package/cross-env ) .
114
107
</Callout >
108
+
109
+ ## NuqsTestingAdapter
110
+
111
+ The ` withNuqsTestingAdapter{:ts} ` function is a higher-order component that
112
+ wraps your component with a ` NuqsTestingAdapter{:ts} ` , but you can also use
113
+ it directly.
114
+
115
+ It takes the following props:
116
+
117
+ - ` searchParams{:ts} ` : The initial search params to use for the test. These can be a
118
+ query string, a ` URLSearchParams ` object or a record object with string values.
119
+
120
+ ``` tsx
121
+ import { NuqsTestingAdapter } from ' nuqs/adapters/testing'
122
+
123
+ <NuqsTestingAdapter searchParams = " ?q=hello&limit=10" >
124
+ <NuqsTestingAdapter searchParams = { new URLSearchParams (" ?q=hello&limit=10" )} >
125
+ <NuqsTestingAdapter searchParams = { {
126
+ q: ' hello' ,
127
+ limit: ' 10' // Values are serialized strings
128
+ }} >
129
+ ```
130
+
131
+ - `onUrlUpdate{ :ts } `, a function that will be called when the URL is updated
132
+ by the component. It receives an object with:
133
+ - the new search params as an instance of `URLSearchParams{ :ts } `
134
+ - the new querystring (for convenience)
135
+ - the options used to update the URL.
136
+
137
+ <details >
138
+ <summary >🧪 Internal/advanced options</summary >
139
+
140
+ - `rateLimitFactor{ :ts } `. By default, rate limiting is disabled when testing,
141
+ as it can lead to unexpected behaviours. Setting this to 1 will enable rate
142
+ limiting with the same factor as in production.
143
+
144
+ - `resetUrlUpdateQueueOnMount{ :ts } `: clear the URL update queue before running the test.
145
+ This is `true{ :ts } ` by default to isolate tests, but you can set it to `false{ :ts } ` to keep the
146
+ URL update queue between renders and match the production behaviour more closely.
147
+
148
+ </details >
0 commit comments