reactjs - 开 Jest : Test useNavigate hook in function component

标签 reactjs react-hooks jestjs react-router-dom

我正在使用 Jest 编写测试,想要测试一个简单的按钮,该按钮用作注销并将您重定向到 "/login"通过onClick .

import {loginService} from "../../utils/loginService";
import React from "react";
import {useNavigate} from "react-router-dom";

const Logout = () => {
    const navigate = useNavigate()

    const logout = e => {
        loginService.logout();
        navigate("/login");
    }

    return (
        <button className={'logout'} onClick={logout}>Logout</button>
    )
}

export default Logout

我能够编写第一个测试来呈现按钮并检查它是否存在。第二个测试应检查单击浏览器时是否会将您重定向到“/login”。

import Logout from "../../components/navbar/Logout";
import {BrowserRouter} from "react-router-dom";
import {fireEvent, render} from "@testing-library/react";
import {screen} from '@testing-library/react';

describe('Test Logout Button', () => {
    it('it is rendered', () => {
        render(
            <BrowserRouter>
                <Logout/>
            </BrowserRouter>
        )
        expect(screen.getByText(/logout/i)).toBeInTheDocument()
    })

    it('it redirects after click', () => {
        const mockedUsedNavigate = jest.fn();

        jest.mock('react-router-dom', () => ({
            ...jest.requireActual('react-router-dom'),
            useNavigate: () => mockedUsedNavigate,
        }));

        render(
            <BrowserRouter>
                <Logout/>
            </BrowserRouter>
        )
        const logout = screen.getByText(/logout/i);

        fireEvent.click(logout);

        // TODO something something check useNavigate
        // https://blog.logrocket.com/testing-react-router-usenavigate-hook-react-testing-library/
        expect(mockedUsedNavigate).toBeCalledTimes(1);
    })
})

然而这失败了:

expect(jest.fn()).toBeCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

我假设我必须以某种方式将模拟传递给我的组件。我该怎么做或者我是否必须这样做?我如何检查 useNavigate已重定向至"/login" ?就我而言<BrowserRouter />没有历史记录属性。

最佳答案

jest.mock 应该在单元测试之外完成,因为它需要在您要测试的代码评估依赖项之前模拟出依赖项。在您的示例中,react-router-dom 库首先由 Logout 组件进行评估,然后您的代码尝试模拟它,但为时已晚。因此,您应该将以下代码移到 describe 之外:

const mockedUsedNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
    ...jest.requireActual('react-router-dom'),
    useNavigate: () => mockedUsedNavigate,
}));

当然,您的所有测试都将使用相同的 mockedUsedNavigate 实例,这可能容易出错,因此您应该在每个单元测试之前重置它,将其添加到 beforeEach 中,如下所示:

beforeEach(() => {
  mockedUsedNavigate.mockReset();
});

关于reactjs - 开 Jest : Test useNavigate hook in function component,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72248371/

相关文章:

javascript - ReactDOM.findDOMNode 未按预期工作

javascript - react : When Does Context Provider Update its Consumers?

reactjs - 是否可以在 React 的 useEffect 中使用自定义钩子(Hook)?

reactjs - React 重写 useEffect 中的 componentWillReceiveProps

reactjs - 如何在 service worker 上访问 Redux 存储

javascript - 开 Jest 深方法 spy

javascript - Jest : How to get arguments passed to mock constructor?

javascript - 将 React 组件渲染为单个 DOM 元素

css - 如何将屏幕右侧的文本移动到屏幕左侧

ios - 从剪贴板粘贴不适用于 iOS 模拟器上的 React Native