4

I have a component that uses useLocation hook to get the path from the URL.

const { pathname } = useLocation();
useEffect(() => { }, [pathname]);

While I am trying to mock the location using ,

import React from 'react';
import ExampleComponent from './ExampleComponent';
import { fireEvent, render } from '@testing-library/react';
import { shallow } from 'enzyme';

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useLocation: () => ({
    pathname: 'https://URL/'
  })
}));

describe('<ExampleComponent />', () => {
  it('should render correctly', () => {
    shallow(<ExampleComponent />);
  });
});

I am getting this error while I run the test, TypeError: Cannot read property 'location' of undefined

Vegeta
  • 109
  • 2
  • 7
  • I would suggest you _don't_ mock it, mount the component in e.g. a MemoryRouter or create a history for testing purposes; see https://stackoverflow.com/a/65275037/3001761, https://reactrouter.com/web/guides/testing – jonrsharpe Jun 14 '21 at 08:34
  • the correct way is to use MemoryRouter as below in the answer https://stackoverflow.com/a/74820547/6127865 – Abasaheb Gaware Dec 16 '22 at 05:43

3 Answers3

4

Try mocking the useLocation as jest.fn().mockImplementation

jest.mock('react-router', () => ({
...jest.requireActual("react-router") as {},
   useLocation: jest.fn().mockImplementation(() => {
    return { pathname: "/testroute" };
   })
}));
Arun Krish
  • 2,153
  • 1
  • 10
  • 15
3

Below is how I have done this in my tests. * Note I am using typescript

import routeData from 'react-router';    

    describe('Login Page UnitTests', () => {
      const useLocation = jest.spyOn(routeData, 'useLocation');
    
      beforeEach(() => {
        useLocation.mockReturnValue({ search: 'testQueryParameters'} as any);
      });

      // Add unit tests
    }

Ensure that you clear the mock to avoid issue with data in subsequent tests

Vuk
  • 693
  • 4
  • 14
  • +1 This is a much cleaner solution. I try to avoid `any` though, so I stubbed out the whole *Location* with `useLocation.mockReturnValue({ pathname: '', search: '', state: {}, hash: '', })` – andyb Feb 24 '22 at 18:41
1

The correct way to mock useLocation is below:

import React from 'react';
import ExampleComponent from './ExampleComponent';
import { fireEvent, render } from '@testing-library/react';
import { MemoryRouter} from 'react-router-dom';
import { shallow } from 'enzyme';

const renderComponent = () => {
  return (
      <MemoryRouter
          initialEntries={["/one", "/two", { pathname: 'https://URL/' }]}
          initialIndex={1}>
         <ExampleComponent />
     </MemoryRouter>
   );
}

describe('<ExampleComponent />', () => {
  it('should render correctly', () => {
    shallow(renderComponent());
  });
});
Abasaheb Gaware
  • 509
  • 4
  • 13