使用< Link />Jest + Testing-Library测试Nextjs

3wabscal  于 2023-04-03  发布在  Jest
关注(0)|答案(1)|浏览(167)

当我测试<Link />行为时,期望它重定向到某个路由,出现了TypeError(Cannot read property 'push' of null)。
这是我目前正在测试的组件:

import React from "react"
import Link from "next/link"

const Sandbox = () => {
  return (
    <div>
      <Link href="/about">
        <a data-testid="mytest">Click Me</a>
      </Link>
    </div>
  )
}

export default Sandbox

这是我正在做的测试

import React from "react"
import { render, fireEvent } from "@testing-library/react"
import { useRouter } from "next/router"
import Sandbox from ".."

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

describe("Sandbox", () => {
  it.only("should navigate accordingly", () => {
    const push = jest.fn()
    useRouter.mockImplementationOnce(() => ({
      asPath: "/",
      push,
    }))

    const { getByTestId } = render(<Sandbox />)

    const mytest = getByTestId("mytest")
    fireEvent.click(mytest)
    expect(push).toHaveBeenCalledWith("/about")
  })
})

我相信我已经嘲笑了我需要的一切,所以我真的不明白为什么路由器实际上不能“推”。我错过了什么?

k4emjkb1

k4emjkb11#

事实证明,需要模拟的模块略有不同(https://github.com/vercel/next.js/issues/7479#issuecomment-797811147)
我自己也有这个问题,所以,基于我的一个测试,应该运行:

import { render, fireEvent, screen } from "@testing-library/react"
import { useRouter } from "next/router"
import Sandbox from ".."
  
jest.mock("next/dist/client/router", () => ({
   useRouter: jest.fn(),
}))
 
describe("Sandbox", () => {
  const mockPush = jest.fn(() => Promise.resolve(true));
   
  beforeAll(() => {
    useRouter.mockReturnValue({
      asPath: "/",
      query: {},
      push: mockPush,
      prefetch: () => Promise.resolve(true)
    })
  })
    
  test("should navigate accordingly", () => {
    
    render(<Sandbox />)
   
    const mytest = screen.getByTestId("mytest")
    fireEvent.click(mytest)
   
    expect(mockPush).toHaveBeenCalledWith("/about", expect.anything(), expect.anything())
  })
})

我添加了expect.anything(),因为push函数可以用它的其他参数调用(https://nextjs.org/docs/api-reference/next/router#routerpush)

相关问题