简体   繁体   中英

Overwriting jest.mock for react-router-dom and useHistory hook

I have a component that uses the useHistory hook.

When I am writing unit test, I mocked the react-route-dom module so that the useHistory hook will be properly mocked in the component that is being tested.

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    location: {
      pathname: 'home',
    },
  }),
}));

However, in one of the tests (named testB ), I would like to overwrite the location.pathname , such that the pathname is of a different value ( help ) from the default mocked value..

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    location: {
      pathname: '/home',
    },
  }),
}));

describe('testing ComponentA', () => {
   afterEach(() => {
      jest.clearAllMocks();
   });

  it('test A', () => {
    // some test
  });

  it('test B', () => {
    jest.mock('react-router-dom', () => ({
      ...jest.requireActual('react-router-dom'),
      useHistory: () => ({
        location: {
          pathname: '/help',
       },
     }),
    }));
    // expect ...
  });

  it('test C', () => {
    // some test
  });
});

However, this does not seem to work as intended, as the inner mock does not seem to overwrite the top level mock. May I know how can this be done? I have searched other similar threads, but they do not work as well.

I managed to archive something similar by mocking the react-router-dom library in a __mocks__ folder, and then mocking the hook individually in each test I needed to override it's return value with mockReturnValue .

// /__mocks__/react-router-dom.js
module.exports = {
  ...jest.requireActual('react-router-dom'),
  useLocation: jest.fn(), // --> you may use useHistory instead
};
it('Should ...', () => {
  // Here mock what you want to test
  useLocation.mockReturnValue({
      search:"?foo=bar",
  });
       ...
  });

In your case using useHistory should be something like

it('Should ...', () => {
  // Here mock what you want to test
  useHistory.mockReturnValue({
   location: {
      pathname: '/home',
    },
  });
       ...
  });

I'd love to know if anyone has a better approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM