如何使用 Jest/React 测试 Router.push

Bro*_*ind 1 javascript reactjs jestjs

我还是单元测试的新手,我很难理解如何测试/模拟来自路由器的推送,

<Tab label="Members" alt="Members" onClick={() => Router.push('/members')}/>
Run Code Online (Sandbox Code Playgroud)

上面这行是我需要测试的,但我怎么能呢?我会创建一个假端点然后测试 onClick 吗?

Was*_*aga 10

就我而言,我使用的是useRouterfromnext/router并使用以下方法解决了它:


import { useRouter } from 'next/router'

jest.mock('next/router', () => ({
  __esModule: true,
  useRouter: jest.fn()
}))

describe('XXX', () => {
  it('XXX', () => {
    const mockRouter = {
      push: jest.fn() // the component uses `router.push` only
    }

    (useRouter as jest.Mock).mockReturnValue(mockRouter)

    expect(mockRouter.push).toHaveBeenCalledWith('/hello/world')
  })
})
Run Code Online (Sandbox Code Playgroud)

原始答案:https ://github.com/vercel/next.js/issues/7479#issuecomment-626297880


Gui*_*uel 8

我收到了一个TypeError: Cannot read property 'push' of undefinedTriny 来模拟 useRouter 的推送。这个解决方案对我有用:

  1. 首先模拟 useRouter
import { useRouter } from "next/router";

jest.mock("next/router", () => ({
  useRouter: jest.fn(),
}));
Run Code Online (Sandbox Code Playgroud)
  1. 然后在你的测试块中像这样使用
const push = jest.fn();

(useRouter as jest.Mock).mockImplementation(() => ({
  push,
}));

userEvent.click(screen.getByRole("button", { name: 'Move to another route' }));
expect(push).toHaveBeenCalledWith("/your-expected-route");
Run Code Online (Sandbox Code Playgroud)

在这里找到这个答案:https://github.com/vercel/next.js/issues/7479#issuecomment-778586840


And*_*rle 6

最简单的方法是像这样模拟路由器

import Router from 'next/router'
jest.mock('next/router', ()=> ({push: jest.fn()}))
Run Code Online (Sandbox Code Playgroud)

模拟点击后,Tab您可以像这样检查呼叫

expect(Router.push).toHaveBeenCalledWith('/members')
Run Code Online (Sandbox Code Playgroud)