Jest - React 测试

在本章中,我们将学习如何使用 Jest 测试 React 组件。Jest 是一个功能强大的测试工具,可让您轻松为 JavaScript 应用程序编写测试。我们将重点关注 React 测试的三个关键领域:

Jest - React 组件测试

在 Jest 中,测试 React 组件涉及渲染它们并检查它们是否显示正确的输出。这通常是使用 React 测试库和 Jest 来完成的。

安装所需的库

在开始之前,请确保已安装 Jest 和 React 测试库:

npm install --save @testing-library/react @testing-library/jest-dom

测试 React 组件

假设我们有一个 Greeting 组件,它接受 name prop 并显示问候语。

// Greeting.js
import React from 'react';

const Greeting = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};

export default Greeting;

为了测试此组件,我们渲染它并检查它是否正确显示问候消息。

// Greeting.test.js
import { render, screen } from '@testing-library/react'; // 导入测试方法
import Greeting from './Greeting'; // 导入组件

test('显示正确的问候消息', () => {
    render(<Greeting name="John" />); // 使用"John"作为 prop 渲染组件
    
    // 检查是否显示问候语
    expect(screen.getByText(/hello, john!/i)).toBeInTheDocument();
});

Jest - 快照测试

Jest 中的快照测试有助于验证您的组件不会意外更改。它捕获组件的渲染输出并保存。在未来的测试中,Jest 会将当前输出与保存的快照进行比较。如果有任何差异,Jest 会提醒您。

快照测试

以下是我们如何使用 Jest 为我们的 Greeting 组件创建快照测试。

// Greeting.test.js
import { render } from '@testing-library/react';
import Greeting from './Greeting';

test('匹配快照', () => {
    const { asFragment } = render(<Greeting name="John" />);
    
    // 将渲染的输出与快照进行比较
    expect(asFragment()).toMatchSnapshot();
});

Jest 在第一次运行时创建快照并将其与未来的输出进行比较。如果输出发生变化,Jest 会提醒您,以便您确认更改是否是故意的。

Jest - 测试 React Hooks

React hooks 管理组件中的状态、副作用和其他逻辑。测试这些 hooks 可确保它们按预期工作。使用 Jest,您可以测试自定义(用户定义)和内置钩子,如 useStateuseEffect

测试自定义钩子

React 中的自定义钩子用于处理可重用逻辑。让我们来看看如何测试一个管理布尔状态的简单自定义钩子。

  • 步骤 1 - 创建 useToggle 钩子: useToggle 钩子切换布尔状态(真/假)。以下是实现:
  • // useToggle.js
    import { useState } from 'react';
    
    const useToggle = () => {
        const [state, setState] = useState(false);
        const toggle = () => setState(!state);
        return { state, toggle };
    };
    
    export default useToggle;
    
  • 第 2 步 - 测试 useToggle Hook:要测试此钩子,我们将使用 @testing-library/react-hooks 中的 renderHook,它允许我们渲染钩子并直接检查其行为。
  • // useToggle.test.js
    从 '@testing-library/react-hooks' 导入 { renderHook, act };
    从 './useToggle' 导入 useToggle;
    
    test('应该在 true 和 false 之间切换状态', () => {
        const { result } = renderHook(() => useToggle());
        
        // 检查初始状态是否为 false
        expect(result.current.state).toBe(false);
        
        // 调用切换函数来更改状态
        act(() => result.current.toggle());
        
        // 检查状态是否更改为 true
        expect(result.current.state).toBe(true);
    });
    

使用副作用测试 useEffect

React 的 useEffect 钩子用于更新 DOM 或获取数据等副作用。在这里,我们将向您展示如何测试使用 useEffect 处理此类副作用的组件。

  • 步骤 1 - 创建计数组件:在这里,我们创建一个 Counter 组件,该组件使用 useState 将初始计数设置为 0,并包含一个按钮以将其增加 1
  • // Counter.js
    import React, { useState } from 'react';
    
    const Counter = () => {
        const [count, setCount] = useState(0);
    
        return (
            <div>
                <p>Count: {count}</p>
                <button onClick={() => setCount(count + 1)}>Increase</button>
            </div>
        );
    };
    
    export default Counter;
    
  • 第 2 步 - 编写测试:现在,让我们编写一个测试来验证单击按钮时计数是否增加。
  • // Counter.test.js
    import { render, screen, fireEvent } from '@testing-library/react';
    import Counter from './Counter';
    
    test('单击按钮时计数器递增', () => {
        // 渲染计数器组件
        render(<Counter />);
        
        // 获取按钮和段落元素
        const button = screen.getByText(/increase/i);
        const passage = screen.getByText(/count: 0/i);
        
        // 模拟单击​​按钮
        fireEvent.click(button);
        
        // 检查计数是否已增加
        expect(paragraph).toHaveTextContent('Count: 1');
    });
    

    此测试验证单击按钮时计数是否从 0 增加到 1