Announcing nuqs version 2
nuqs

Testing

Some tips on testing components that use `nuqs`

Since nuqs 2, you can unit-test components that use useQueryState(s) hooks by wrapping your rendered component in a NuqsTestingAdapter.

With Vitest

Here is an example for Vitest and Testing Library to test a button rendering a counter:

counter-button.test.tsx
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()
  const event = onUrlUpdate.mock.calls[0][0]!
  expect(event.queryString).toBe('?count=43')
  expect(event.searchParams.get('count')).toBe('43')
  expect(event.options.history).toBe('push')
})

See issue #259 for more testing-related discussions.

With Jest

Since nuqs 2 is an ESM-only package, there are a few hoops you need to jump through to make it work with Jest. This is extracted from the Jest ESM guide.

  1. Add the following options to your jest.config.ts file:
jest.config.ts
const config: Config = {
  // <Other options here>

  extensionsToTreatAsEsm: [".ts", ".tsx"],
  transform: {}
};
  1. Change your test command to include the --experimental-vm-modules flag:
package.json
{
  "scripts": {
    "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest"
  }
}

Adapt accordingly for Windows with cross-env.

Higher-order component

Creating a wrapper component to pass props to the NuqsTestingAdapter can be verbose as your test suite grows.

You can use the withNuqsTestingAdapter function to pass the right props, and it will return a wrapper component:

import { withNuqsTestingAdapter } from 'nuqs/adapters/testing'
 
render(<CounterButton />, {
  wrapper: withNuqsTestingAdapter({ searchParams: '?count=42', onUrlUpdate })
})

On this page