#Testing component with useSearchParams

3 messages · Page 1 of 1 (latest)

severe summit
#

I have a client component that has a caller to useSearchParams. I'm using this to add query params to the route for errors

export default function Thing() {
  const searchParams = useSearchParams()
  const possibleError = searchParams.get('error')

  return (
    <div>
      {possibleError ? <span>some error</span> : null}
      <span>Stuff here</span>
    </div>
  )
}

Naive but you get the point. If the component is mounted and the uri has a query error I display an error. In practice this works. I have a component that conditionally renders an error when the search query is present.

Now, I'm trying to test this.

For starters I had to mock next/navigation just to keep TypeError: Cannot read properties of undefined (reading 'get') errors from jest.

So I have

jest.mock('next/navigation', () => {
    return {
        __esModule: true,
        useSearchParams: () => ({
            get: jest.fn(),
        }),
    }
})

But I can't for the life of me figure out how to mock the response of get in a single test.

I would like to assert the actual value of the query param as well.
So something like error=foo and error=bar

I am on Next 14 and using the app router.
Jest
React-testing-library
Typescript

viscid sunBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

severe summit
#

I got it.

I changed the mock to

jest.mock('next/navigation', () => {
    return {
        __esModule: true,
        useSearchParams: jest.fn().mockImplementation(() => new URLSearchParams()),
    }
})

And in the test I did this

;(useSearchParams as jest.Mock).mockImplementation(() => new URLSearchParams('signInError=invalidSession'))

I was trying to mock the get method off of the constructor of URLSearchParams which is the actual function in useSearchParams it's just a readonly version.

So by changing the mock to mock out useSearchParams to itself being a mock implementing URLSearchParams I was able to then update the mock inside a single test.

test('Should show an error', () => {
        ;(useSearchParams as jest.Mock).mockImplementation(() => new URLSearchParams('signInError=invalidSession'))

        const {getByText} = render(<LoginModal header={<span>Testing Header</span>} />)

        expect(getByText('Invalid Session. Please login agin.')).toBeInTheDocument()
    })