TypeError: Cannot read property 'startsWith' of undefined in router.pathname.startsWith()

TypeError: Cannot read property 'startsWith' of undefined in router.pathname.startsWith()

我正在为 NextJS 中的 TDD 使用 Jest 和 React 测试库,在导航组件中我正在使用代码

<li className={router.pathname.startsWith('/settings/employeetypes') ? "active-link" : ""}>
 <a className="dropdown-item" href="#">Employee Type</a>
</li>

主页组件中正在使用导航组件。

测试文件是:

import React from 'react'
import { render, screen } from '@testing-library/react'
import * as nextRouter from 'next/router';
import '@testing-library/jest-dom'
nextRouter.useRouter = jest.fn();
nextRouter.useRouter.mockImplementation(() => ({ route: '/' }));
import Home from '../pages/index'

describe('Home', () => {
  it('Home Page renders a NavBar', () => {    
      render(<Home />)
      expect(screen.getByText(/live/i)).toBeInTheDocument();
  })

  it('Homepage should display app-wrapper class',() => {
    const { container } = render(<Home />)
    expect(container.getElementsByClassName('app-wrapper').length).toBe(1);
  })

  it('Homepage should display map',() => {
    const { container } = render(<Home  />)
    expect(container.firstChild).toMatchSnapshot();
  })
})

首页组件代码为:

import axios from 'axios'
import NavBar from '@/components/NavBar'
import { useRef, useEffect } from 'react'
import { loadModules } from 'esri-loader'

export default function Home({...props}) {

  useEffect(() => {
     // some stuff there 
  })

  return (
    <div id="home-container"> 
        <NavBar />
        ....
        .... 
    </div>
}

export async function getServerSideProps(context) {
   ... // Call API for get data for Home Component
}

导航栏组件代码:

import Link from "next/link";
import { useRouter } from "next/router";

const NavBar = ({...props}) => {
   const router = useRouter();

   return (
          <ul className="dropdown-menu" aria-labelledby="navbarDropdown">
               <li className={router.pathname == "/" ? "active-link nav-item" : "nav-item"}>
                        <Link href="/">
                            <a className="nav-link">
                                <span className="nav-icon">
                                    <img src="/icons/dashboard.png" />
                                </span>
                                <span className="nav-link-text">Live View</span>
                            </a>
                            </Link>
                 </li>

                  <li className={router.pathname.startsWith('/settings/locations') ? "active-link" : ""}>
                    <Link href="/settings/locations">
                       <a className="dropdown-item">Locations</a>
                     </Link>
                  </li>
            </ul>
   )
 }

您可以将 useRouter() 模拟为 return 像 {pathname: "/settings/locations"} 这样的对象。然后 router.pathname 不再是 undefined 并且有一个 startsWith() 方法。

您只需修改测试文件中的现有行:

nextRouter.useRouter.mockImplementation(() => ({ route: '/', pathname: '/' })); // or which pathname you want to test