React 中的单元测试 NavLink 导航

问题描述 投票:0回答:1

我正在使用React v18.2.0和React测试库v5.17.0。

我应该如何对导航栏中的 NavLinks 进行单元测试?

我认为这个测试应该有效,但我收到错误:

Expected: "about"
Received: "about", {"preventScrollReset": undefined, "relative": undefined, "replace": false, "state": undefined, "unstable_viewTransition": undefined}

看起来好像有一个对象和路线一起被传递,导致测试失败?

我的导航栏:

const NavBar = () => {

  return (
    <>
        <div className="navbar">
            <ul>
                <li>
                  <NavLink to="home" className="navlink">Home</NavLink>
                </li>
                <li>
                  <NavLink to="about" className="navlink">About</NavLink>
                </li>
            </ul> 
        </div>
    </>
  );
};

export default Navbar;

我的单元测试:

import { render, fireEvent } from "@testing-library/react";
import NavBar from './NavBar';
import * as router from 'react-router';
import { BrowserRouter as Router } from 'react-router-dom';

describe(NavBar, () => {
    const mockedNavigation = jest.fn();
    
    const MockedNav = () => {
        return(
            <Router>
                <Navbar />
            </Router>
        )
    }

    beforeEach(() => {
        jest.spyOn(router, 'useNavigate').mockImplementation(() => mockedNavigation)
    })
        
    it('should navigate to the about page', () => {
        const { getByText } = render(<MockedNav />);
        fireEvent.click(getByText(/About/i));

        expect(mockedNavigation).toHaveBeenCalledWith("about");
    });
})
reactjs jestjs react-router react-testing-library
1个回答
0
投票

问题

您正在嘲笑的函数传递了这些其他参数。

解决方案

  • 您可以简单地将附加参数添加到测试中:

    describe(NavBar, () => {
      const mockedNavigation = jest.fn();
    
      beforeEach(() => {
        jest.spyOn(router, 'useNavigate').mockImplementation(() => mockedNavigation
      }
    
      it('should navigate to the about page', () => {
        const { getByText } = render(<Navbar />, { wrapper: Router });
        fireEvent.click(getByText(/About/i));
    
        expect(mockedNavigation).toHaveBeenCalledWith(
          "about",
          {
            preventScrollReset: undefined,
            relative: undefined,
            replace: false,
            state: undefined,
            unstable_viewTransition: undefined
          }
        );
      });
    })
    
  • 您可以断言模拟已被调用,并且 first 参数正是您所期望的:

    describe(NavBar, () => {
      const mockedNavigation = jest.fn();  
    
      beforeEach(() => {
        jest.spyOn(router, 'useNavigate').mockImplementation(() => mockedNavigation
      });
    
      it('should navigate to the about page', () => {
        const { getByText } = render(<Navbar />, { wrapper: Router });
        fireEvent.click(getByText(/About/i));
    
        expect(mockedNavigation).toHaveBeenCalled();
        expect(mockedNavigation.mock.calls[0][0]).toEqual("about");
      });
    });
    
  • 或者您可以使用非对称匹配器来断言第二个参数中传递的任何内容(因为看起来您并不关心该特定值是什么):

    describe(NavBar, () => {
      const mockedNavigation = jest.fn();
    
      beforeEach(() => {
        jest.spyOn(router, 'useNavigate').mockImplementation(() => mockedNavigation
      }
    
      it('should navigate to the about page', () => {
        const { getByText } = render(<Navbar />, { wrapper: Router });
        fireEvent.click(getByText(/About/i));
    
        expect(mockedNavigation).toHaveBeenCalledWith(
          "about",
          expect.anything(),
        );
      });
    })
    
© www.soinside.com 2019 - 2024. All rights reserved.