Seeking suggestions for mocking/spying on calls to navigate()

I have a simplified example here of a component I’m trying to test.

I want to click on a button that triggers a navigate() and assert that it was called with the correct arguments.

Any tips on how best to do this? Thank you!

Component:

import { navigate, routes } from '@redwoodjs/router'

const MyComponent = () => {
    const handleNavigation = () => navigate(routes.dashboard({ id: 'foo' }))

    return <button onClick={handleNavigation}>Dashboard</button>
}

Test:

import { screen, fireEvent } from '@redwoodjs/testing/web'

  it('navigates to dashboard', async () => {
    expect(() => {
      render(<MyComponent />)
    }).not.toThrow()
    
    const navigateButton = screen.getByText('Dashboard')
    fireEvent.click(navigateButton)

   // TODO - want to assert that navigate() was called with the `{ id: 'foo' }` argument
})

This might work

import { screen, fireEvent } from '@redwoodjs/testing/web'
import { navigate } from '@redwoodjs/router'

it('navigates to dashboard', async () => {
  // Create a mock implementation of the navigate function
  const navigateMock = jest.fn()
  navigate.mockImplementation(navigateMock)

  render(<MyComponent />)

  const navigateButton = screen.getByText('Dashboard')
  fireEvent.click(navigateButton)

  expect(navigateMock).toHaveBeenCalledWith(routes.dashboard({ id: 'foo' }))
})
1 Like

Thanks for your help!

Property 'mockImplementation' does not exist on type '(to: string, options?: NavigateOptions | undefined) => void'

I don’t think this works because the navigate object doesn’t have the mockImplementation method on it.