title: Mocking NextJS router events with Jest
body: <p>I am trying to mock NextJS router events with Jest. Found a relevant resource right here at <a href="https://stackoverflow.com/questions/59961579/nextjs-router-jest-how-can-i-mock-router-change-event">NextJS router &amp; Jest</a>. The implementation there is very similar to mine.</p>
  <p>However, the solution mentioned there is not working for me.</p>
  <p>My test is below:</p>
  <pre><code>import { mount, ReactWrapper } from 'enzyme';
  import FavoritesPage from 'pages/user/favorites';
  import configureStore, { MockStore } from 'redux-mock-store';
  import storeInitialState from '__tests__/unit/support/storeInitialState';
  import { Provider } from 'react-redux';
  import { waitFor } from '@testing-library/react';
  import { RequestStates } from 'types/State';
  import useAdSetup from 'lib/hooks/useAdSetup';
  import { AgeType, PageType } from 'lib/CarGurusAds/TaxonomySchema';
  
  const mockRequestState = RequestStates.Finished;
  
  jest.mock('lib/Auth');
  jest.mock('lib/EventLogger');
  jest.mock('lib/hooks/useAdSetup');
  
  jest.mock('lib/hooks/useFetchFavorites', () =&gt; {
    return (): { requestState: RequestStates } =&gt; {
      return {
        requestState: mockRequestState,
      };
    };
  });
  
  jest.mock('next/router');
  
  const mockStore = configureStore();
  
  let store: MockStore;
  
  describe('when clicking the price drop subnav button', () =&gt; {
    let component: ReactWrapper;
  
    beforeEach(async () =&gt; {
      store = mockStore(storeInitialState);
      await waitFor(() =&gt; {
        component = mount(
          &lt;Provider store={store}&gt;
            &lt;FavoritesPage /&gt;
          &lt;/Provider&gt;
        );
      });
      component.find('.price-drop-nav-item').simulate('click');
    });
  
    it('shows price drops', () =&gt; {
      let eventName;
      let routeChangeHandler;
      let useRouter = jest.fn();
  
      useRouter.mockImplementation(() =&gt; {
        return {
          events: {
            on: jest.fn((event, callback) =&gt; {
              eventName = event;
              routeChangeHandler = callback;
            }),
            off: jest.fn((event, callback) =&gt; {
              eventName = event;
              routeChangeHandler = callback;
            }),
          },
        };
      });
    
      expect(useRouter).toHaveBeenCalledTimes(1);
      expect(component.find('.price-drop-nav-item').hasClass('active')).toBeTruthy();
    });
  });
  </code></pre>
  <p>Inside, my component just like the referenced example has the following:</p>
  <pre><code>  useEffect(() =&gt; {
      const handleComplete: any = async (url: string) =&gt; {
        if (window) {
          await trackReturnToSeachClick(url);
        }
      };
      router.events.on('routeChangeComplete', handleComplete);
      router.events.on('routeChangeError', handleComplete);
  
      // Cleanup event listeners
      return (): void =&gt; {
        router.events.off('routeChangeComplete', handleComplete);
        router.events.off('routeChangeError', handleComplete);
      };
    }, [router]);
  </code></pre>
  <p>Unlike the referenced example, when I run my code, I am still getting the below error:</p>
  <pre><code>TypeError: Cannot read property 'on' of undefined
  </code></pre>
  <p>What am I missing?</p>