Skip to content

Commit

Permalink
doc: Add section on testing
Browse files Browse the repository at this point in the history
  • Loading branch information
franky47 committed Oct 21, 2024
1 parent 9f6df68 commit 8220127
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 12 deletions.
12 changes: 5 additions & 7 deletions errors/NUQS-404.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ You haven't wrapped the components calling `useQueryState(s)` with
an adapter.

[Adapters](https://nuqs.47ng.com/docs/adapters) are based on React Context,
and provide nuqs hooks with the interfaces to work with your framework.
and provide nuqs hooks with the interfaces to work with your framework:
reacting to URL changes, and calling your router when you update your state.

## Possible solutions

Expand All @@ -22,9 +23,6 @@ using a suitable adapter:
### Test adapter

If you encounter this error outside of the browser, like in a test
runner, you may use the test adapter from `nuqs/adapters/test`
to mock the context and access setup/assertion testing facilities.

```tsx

```
runner (eg: Vitest or Jest), you may use the [testing adapter](https://nuqs.47ng.com/docs/testing)
from `nuqs/adapters/testing` to mock the initial search params and access
setup/assertion testing facilities.
40 changes: 35 additions & 5 deletions packages/docs/content/docs/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,41 @@ title: Testing
description: Some tips on testing components that use `nuqs`
---

Currently, the best way to test the behaviour of your components using
`useQueryState(s)` is end-to-end testing, with tools like Playwright or Cypress.
Since nuqs 2, you can unit-test components that use `useQueryState(s){:ts}` hooks
by wrapping your rendered component in a `NuqsTestingAdapter{:ts}`.

Running components that use the Next.js router in isolation requires mocking it,
which is being [worked on](https://github.com/scottrippey/next-router-mock/pull/103)
for the app router.
Here is an example for Vitest and Testing Library to test a button rendering
a counter:

```tsx title="counter-button.test.tsx"
// [!code word:NuqsTestingAdapter]
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { NuqsTestingAdapter, type UrlUpdateEvent } from 'nuqs/adapters/testing'
import { describe, expect, it, vi } from 'vitest'
import { CounterButton } from './counter-button'

it('should increment the count when clicked', async () => {
const user = userEvent.setup()
const onUrlUpdate = vi.fn<[UrlUpdateEvent]>()
render(<CounterButton />, {
// 1. Setup the test by passing initial search params / querystring:
wrapper: ({ children }) => (
<NuqsTestingAdapter searchParams="?count=42" onUrlUpdate={onUrlUpdate}>
{children}
</NuqsTestingAdapter>
)
})
// 2. Act
const button = screen.getByRole('button')
await user.click(button)
// 3. Assert changes in the state and in the (mocked) URL
expect(button).toHaveTextContent('count is 43')
expect(onUrlUpdate).toHaveBeenCalledOnce()
expect(onUrlUpdate.mock.calls[0][0].queryString).toBe('?count=43')
expect(onUrlUpdate.mock.calls[0][0].searchParams.get('count')).toBe('43')
expect(onUrlUpdate.mock.calls[0][0].options.history).toBe('push')
})
```

See issue [#259](https://github.com/47ng/nuqs/issues/259) for more testing-related discussions.

0 comments on commit 8220127

Please sign in to comment.