反应笑话模拟 useNavigate()

Zac*_*Zac 39 mocking reactjs jestjs react-router-dom react-hooks

"react-router-dom": "^6.0.0-alpha.5",
Run Code Online (Sandbox Code Playgroud)

我几乎尝试了一切。

我只是想从钩子上模拟这个navigate()调用useNavigate()。就是这样。简单的。没有任何作用。

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

"react-router-dom": "^6.0.0-alpha.5",
Run Code Online (Sandbox Code Playgroud)

我已经尝试过这些:

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')
    };
});
Run Code Online (Sandbox Code Playgroud)
import * as ReactRouterDom from "react-router-dom";
...
// cannot redefine property
          Object.defineProperty(ReactRouterDom, 'useNavigate', {
              configurable: true,
              value: jest.fn(() => 'bar')
          });
Run Code Online (Sandbox Code Playgroud)
// doesnt work
          jest.mock('react-router-dom', () => ({
              useNavigate: jest.fn(() => jest.fn),
          }))
Run Code Online (Sandbox Code Playgroud)
// doesnt work
jest.spyOn(ReactRouterDom, 'useNavigate', 'get').mockReturnValue(jest.fn(() => jest.fn));
Run Code Online (Sandbox Code Playgroud)
// doesnt work
jest.spyOn(ReactRouterDom, 'useNavigate').mockReturnValue(jest.fn(() => jest.fn));
Run Code Online (Sandbox Code Playgroud)
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>
    )
}
Run Code Online (Sandbox Code Playgroud)

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

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

我究竟做错了什么?

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

exa*_*cae 83

我也有类似的担忧,该问题已通过反应路由器解决

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

// 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

Run Code Online (Sandbox Code Playgroud)

  • 你的 mokedUseNavigate 和 jest 模拟(https://github.com/zacharytyhacz/useNavigateBug/blob/86ac42296a07af65f15ca1298817add5ac486310/tests/Home.test.tsx#L63)应该位于文件的顶层,而不是在“test”,“it”内”或“描述”:请参阅此参考:https://github.com/ReactTraining/react-router/issues/7811 (4认同)
  • @Zac请尝试渲染(&lt;BrowserRouter&gt;&lt;YourComponent /&gt;&lt;/BrowserRouter&gt;) (2认同)

Paw*_*cki 28

navigate()以下是我在组件测试中模拟和断言调用的方式:

import * as router from 'react-router'

const navigate = jest.fn()

beforeEach(() => {
  jest.spyOn(router, 'useNavigate').mockImplementation(() => navigate)
})

it('...', () => {
  ...
  expect(navigate).toHaveBeenCalledWith('/path')
})

Run Code Online (Sandbox Code Playgroud)


ssc*_*lli 11

useNavigate如果您从以下位置更改导入,您应该能够正常监视:

import { useNavigate } from "react-router-dom"
Run Code Online (Sandbox Code Playgroud)

import { useNavigate } from "react-router"
Run Code Online (Sandbox Code Playgroud)