反应玩笑模拟 useNavigate()

时间:2021-02-19 20:03:15

标签: reactjs jestjs mocking react-hooks react-router-dom

"react-router-dom": "^6.0.0-alpha.5",

我几乎什么都试过了。

我只想模拟来自 navigate() 钩子的这个 useNavigate() 调用。而已。简单的。没有任何效果。

不,我不想使用 Link。 useNavigate 在其他地方也以编程方式使用,我也想模拟它们

import React from 'react'
import { useNavigate } from "react-router-dom"

export const Detail = () => {
    const navigate = useNavigate();
    return (
        <span onClick={() => navigate('/some/specific/route')}>
            some Text
        </span>
    )
}

我已经尝试过这些:

jest.mock('react-router-dom', () => {
    // Require the original module to not be mocked...
    const originalModule = jest.requireActual('react-router-dom');

    return {
        __esModule: true,
        ...originalModule,
        // add your noops here
        useNavigate: jest.fn(() => 'bar')
    };
});
import * as ReactRouterDom from "react-router-dom";
...
// cannot redefine property
          Object.defineProperty(ReactRouterDom, 'useNavigate', {
              configurable: true,
              value: jest.fn(() => 'bar')
          });
// doesnt work
          jest.mock('react-router-dom', () => ({
              useNavigate: jest.fn(() => jest.fn),
          }))
// doesnt work
jest.spyOn(ReactRouterDom, 'useNavigate', 'get').mockReturnValue(jest.fn(() => jest.fn));
// doesnt work
jest.spyOn(ReactRouterDom, 'useNavigate').mockReturnValue(jest.fn(() => jest.fn));
// doesnt work
const mockedUsedNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
   ...jest.requireActual('react-router-dom') as any,
  useNavigate: () => mockedUsedNavigate,
}));

所有这些要么显示"Cannot redefine Property 'useNavigate'",要么显示 useNavigate() may be used only in the context of a <Router> component.

说真的,任何其他导入模拟都可以正常工作。

我做错了什么?

我最小的重新创建项目:https://github.com/zacharytyhacz/useNavigateBug

1 个答案:

答案 0 :(得分:2)

我有一个类似的问题,this issue from react router

我建议您按原样更改模拟:

// pay attention to write it at the top level of your file
const mockedUsedNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
   ...jest.requireActual('react-router-dom') as any,
  useNavigate: () => mockedUsedNavigate,
}));


// your describe/it/test blocks go down there