@@ -4,10 +4,28 @@ 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} ` , or using
8
- the ` withNuqsTestingAdapter{:ts} ` higher-order component.
7
+ without needing to mock anything, by using a dedicated testing adapter that will
8
+ facilitate ** setting up** your tests (with initial search params) and ** asserting**
9
+ on URL changes when ** acting** on your components.
9
10
10
- ## With Vitest
11
+ ## Testing hooks with React Testing Library
12
+
13
+ When testing hooks that rely on nuqs' ` useQueryState(s){:ts} ` with React Testing Library's
14
+ [ ` renderHook{:ts} ` ] ( https://testing-library.com/docs/react-testing-library/api/#renderhook ) function,
15
+ you can use ` withNuqsTestingAdapter{:ts} ` to get a wrapper component to pass to the
16
+ ` renderHook{:ts} ` call:
17
+
18
+ ``` tsx
19
+ import { withNuqsTestingAdapter } from ' nuqs/adapters/testing'
20
+
21
+ const { result } = renderHook (() => useTheHookToTest (), {
22
+ wrapper: withNuqsTestingAdapter ({
23
+ searchParams: { count: " 42" },
24
+ }),
25
+ })
26
+ ```
27
+
28
+ ## Testing components with Vitest
11
29
12
30
Here is an example for Vitest and Testing Library to test a button rendering
13
31
a counter:
@@ -74,15 +92,15 @@ it('should increment the count when clicked', async () => {
74
92
75
93
See issue [ #259 ] ( https://github.com/47ng/nuqs/issues/259 ) for more testing-related discussions.
76
94
77
- ## With Jest
95
+ ## Jest and ESM
78
96
79
97
Since nuqs 2 is an [ ESM-only package] ( https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c ) ,
80
98
there are a few hoops you need to jump through to make it work with Jest.
81
99
This is extracted from the [ Jest ESM guide] ( https://jestjs.io/docs/ecmascript-modules ) .
82
100
83
101
1 . Add the following options to your jest.config.ts file:
84
102
85
- ``` ts title="jest.config .ts"
103
+ ``` ts title="jest.configx .ts"
86
104
const config: Config = {
87
105
// <Other options here>
88
106
// [!code highlight:3]
@@ -106,44 +124,34 @@ const config: Config = {
106
124
Adapt accordingly for Windows with [ ` cross-env ` ] ( https://www.npmjs.com/package/cross-env ) .
107
125
</Callout >
108
126
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.
127
+ ## API
114
128
115
- It takes the following props :
129
+ ` withNuqsTestingAdapter{:ts} ` accepts the following arguments :
116
130
117
131
- ` searchParams{:ts} ` : The initial search params to use for the test. These can be a
118
132
query string, a ` URLSearchParams ` object or a record object with string values.
119
133
120
134
``` 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
- ```
135
+ withNuqsTestingAdapter ({
136
+ searchParams: ' ?q=hello&limit=10'
137
+ })
130
138
131
- When testing hooks that rely on nuqs' `useQueryState(s){ :ts } ` with React Testing Library's
132
- [`renderHook{ :ts } `](https://testing-library.com/docs/react-testing-library/api/#renderhook) function,
133
- you can use the `withNuqsTestingAdapter{ :ts } ` as a wrapper component passed into the
134
- `renderHook{ :ts } ` call.
139
+ withNuqsTestingAdapter ({
140
+ searchParams: new URLSearchParams (' ?q=hello&limit=10' )
141
+ })
135
142
136
- ```tsx
137
- const { result } = renderHook(() => useMyNiceHook(), { wrapper : withNuqsTestingAdapter ({
138
- searchParams: { q: ' hello-world' }
139
- }) } )
143
+ withNuqsTestingAdapter ({
144
+ searchParams: {
145
+ q: ' hello' ,
146
+ limit: ' 10' // Values are serialized strings
147
+ }
148
+ })
140
149
```
141
150
142
-
143
- - `onUrlUpdate{ :ts } `, a function that will be called when the URL is updated
151
+ - ` onUrlUpdate{:ts} ` : a function that will be called when the URL is updated
144
152
by the component. It receives an object with:
145
153
- the new search params as an instance of ` URLSearchParams{:ts} `
146
- - the new querystring (for convenience)
154
+ - the new renderd query string (for convenience)
147
155
- the options used to update the URL.
148
156
149
157
<details >
@@ -158,3 +166,21 @@ This is `true{:ts}` by default to isolate tests, but you can set it to `false{:t
158
166
URL update queue between renders and match the production behaviour more closely.
159
167
160
168
</details >
169
+
170
+
171
+ ## NuqsTestingAdapter
172
+
173
+ The ` withNuqsTestingAdapter{:ts} ` function is a wrapper component factory function
174
+ wraps children with a ` NuqsTestingAdapter{:ts} ` , but you can also use
175
+ it directly:
176
+
177
+ ``` tsx
178
+ // [!code word:NuqsTestingAdapter]
179
+ import { NuqsTestingAdapter } from ' nuqs/adapters/testing'
180
+
181
+ <NuqsTestingAdapter >
182
+ <ComponentsUsingNuqs />
183
+ </NuqsTestingAdapter >
184
+ ```
185
+
186
+ It takes the same props as the arguments you can pass to ` withNuqsTestingAdapter{:ts} ` .
0 commit comments