如何使用Jest模拟新的React Router Hooks的history.push [英] How to mock history.push with the new React Router Hooks using Jest

查看:414
本文介绍了如何使用Jest模拟新的React Router Hooks的history.push的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在react-router上新的useHistory挂钩内模拟history.push并使用@testing-library/react.我只是像第一个答案一样嘲笑该模块:如何进行测试组件使用新的React Router钩子?

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?

我正在这样做:

//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');
  });
})

但是mockHistoryPush没有被调用...我在做什么错了?

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

推荐答案

在模块范围内使用jest.mock会自动提升到代码块的顶部.这样您就可以在NotFound.jsx文件和测试文件中获得模拟版本react-router-dom.

Use jest.mock in module scope will automatically be hoisted to the top of the code block. So that you can get the mocked version react-router-dom in NotFound.jsx file and your test file.

此外,我们只想模拟useHistory钩子,因此我们应该使用jest.requireActual()来获取原始模块,并将其他方法保留为原始版本.

Besides, we only want to mock useHistory hook, so we should use jest.requireActual() to get the original module and keep other methods as the original version.

这是解决方案:

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');
  });
});

单元测试结果覆盖率100%:

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

源代码: https://github.com/mrdulin /jest-codelab/tree/master/src/stackoverflow/58524183

这篇关于如何使用Jest模拟新的React Router Hooks的history.push的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆