How to mock history.push with the new React Router Hooks using Jest

生来就可爱ヽ(ⅴ<●) 提交于 2020-06-14 06:02:34

问题


I am trying to mock history.push inside the new useHistory hook on react-router and using @testing-library/react. I just mocked the module like the first answer here: How to test components using new react router hooks?

So I am doing:

//NotFound.js
import * as React from 'react';
import { useHistory } from 'react-router-dom';


const RouteNotFound = () => {
  const history = useHistory();
  return (
    <div>
      <button onClick={() => history.push('/help')} />
    </div>
  );
};

export default RouteNotFound;
//NotFound.test.js
describe('RouteNotFound', () => {
  it('Redirects to correct URL on click', () => {
    const mockHistoryPush = jest.fn();

    jest.mock('react-router-dom', () => ({
      ...jest.requireActual('react-router-dom'),
      useHistory: () => ({
        push: mockHistoryPush,
      }),
    }));

    const { getByRole } = render(
        <MemoryRouter>
          <RouteNotFound />
        </MemoryRouter>
    );

    fireEvent.click(getByRole('button'));
    expect(mockHistoryPush).toHaveBeenCalledWith('/help');
  });
})

But mockHistoryPush is not called... What am I doing wrong?


回答1:


You can't use jest.mock in function scope. It should be put in module scope. Here is the solution:

NotFound.jsx:

import React from 'react';
import { useHistory } from 'react-router-dom';

const RouteNotFound = () => {
  const history = useHistory();
  return (
    <div>
      <button onClick={() => history.push('/help')} />
    </div>
  );
};

export default RouteNotFound;

NotFound.test.jsx:

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

const mockHistoryPush = jest.fn();

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    push: mockHistoryPush,
  }),
}));

describe('RouteNotFound', () => {
  it('Redirects to correct URL on click', () => {
    const { getByRole } = render(
      <MemoryRouter>
        <RouteNotFound />
      </MemoryRouter>,
    );

    fireEvent.click(getByRole('button'));
    expect(mockHistoryPush).toHaveBeenCalledWith('/help');
  });
});

Unit test result with 100% coverage:

PASS  src/stackoverflow/58524183/NotFound.test.jsx
  RouteNotFound
    ✓ Redirects to correct URL on click (66ms)

--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |      100 |      100 |      100 |      100 |                   |
 NotFound.jsx |      100 |      100 |      100 |      100 |                   |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.133s, estimated 11s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58524183



来源:https://stackoverflow.com/questions/58524183/how-to-mock-history-push-with-the-new-react-router-hooks-using-jest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!