当前位置: 首页 > news >正文

Jest进阶知识:React组件的单元测试

在现代前端开发中,组件是构建应用程序的基本单元。一个组件不仅拥有完整的功能,还能极大地提高代码的复用性。因此,在进行单元测试时,对重要组件进行测试是必不可少的。

Testing Library

Testing Library 是一个专门用于测试 Web 组件的工具库,其设计理念是“测试组件的行为而不是实现细节”。通过 Testing Library 提供的一系列 API,可以模拟浏览器中的用户交互方式,使测试更加贴近真实使用场景。

Jest 与 Testing Library 的关系

  • Jest:一个完整的测试框架,提供了匹配器、mock 库、断言工具等,旨在提供一个全面的测试工具链。
  • Testing Library:一个测试工具库,专注于测试组件的行为。它可以与各种框架结合使用,提供了一组用于测试 React 组件的工具,如 renderscreenfireEvent 等。

常用的 Testing Library 扩展库

  • @testing-library/react:提供了一组用于测试 React 组件的工具,如 renderscreenfireEvent
  • @testing-library/jest-dom:提供了一组 Jest 断言方法,用于测试 DOM 元素的状态和行为,如 toBeInTheDocumenttoHaveTextContent 等。
  • @testing-library/user-event:提供了一组用于模拟用户行为的工具,如 typeclicktab 等。

核心 API

render 方法

render 方法接收一个组件作为参数,将其渲染为 DOM 元素,并返回一个包含重要属性的对象:

  • container:渲染后的 DOM 元素,可用于模拟用户行为或进行断言验证。
  • baseElement:整个文档的根元素 <html>
  • asFragment:将渲染后的 DOM 元素转换为 DocumentFragment 对象,便于进行快照测试。
  • debug:在控制台输出渲染后的 DOM 元素的 HTML 结构,便于调试。

screen 对象

screen 对象封装了一系列常用的 DOM 查询和操作函数:

  • getByLabelText:根据 <label> 元素的 for 属性或内部文本,获取与之关联的表单元素。
  • getByText:根据文本内容获取元素。
  • getByRole:根据 role 属性获取元素。
  • getByPlaceholderText:根据 placeholder 属性获取表单元素。
  • getByTestId:根据 data-testid 属性获取元素。
  • queryBy*:类似于 getBy*,但当元素不存在时返回 null 而不是抛出异常。

测试组件示例

示例一:隐藏消息组件

import { useState } from "react";function HiddenMessage({ children }) {const [isShow, setIsShow] = useState(false);return (<div><label htmlFor="toggle">显示信息</label><inputtype="checkbox"name="toggle"id="toggle"checked={isShow}onChange={(e) => setIsShow(e.target.checked)}/>{isShow ? children : null}</div>);
}export default HiddenMessage;

该组件接收一个子组件,并根据复选框的状态决定是否显示子组件。以下是对应的测试代码:

import { render, screen, fireEvent } from "@testing-library/react";
import HiddenMessage from "../HiddenMessage";test("能够被勾选,功能正常", () => {const testMessage = "这是一条测试信息";render(<HiddenMessage>{testMessage}</HiddenMessage>);// 初始状态下,信息不应显示expect(screen.queryByText(testMessage)).toBeNull();// 模拟点击复选框fireEvent.click(screen.getByLabelText("显示信息"));// 信息应显示expect(screen.getByText(testMessage)).toBeInTheDocument();
});

示例二:登录组件

import * as React from "react";function Login() {const [state, setState] = React.useReducer((s, a) => ({ ...s, ...a }),{ resolved: false, loading: false, error: null });function handleSubmit(event) {event.preventDefault();const { usernameInput, passwordInput } = event.target.elements;setState({ loading: true, resolved: false, error: null });window.fetch("/api/login", {method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({username: usernameInput.value,password: passwordInput.value,}),}).then((r) =>r.json().then((data) => (r.ok ? data : Promise.reject(data)))).then((user) => {setState({ loading: false, resolved: true, error: null });window.localStorage.setItem("token", user.token);},(error) => {setState({ loading: false, resolved: false, error: error.message });});}return (<div><form onSubmit={handleSubmit}><div><label htmlFor="usernameInput">Username</label><input id="usernameInput" /></div><div><label htmlFor="passwordInput">Password</label><input id="passwordInput" type="password" /></div><button type="submit">Submit{state.loading ? "..." : null}</button></form>{state.error ? <div role="alert">{state.error}</div> : null}{state.resolved ? (<div role="alert">Congrats! You're signed in!</div>) : null}</div>);
}export default Login;

该组件处理用户的登录请求,根据请求结果显示不同的信息。以下是对应的测试代码:

import { rest } from "msw";
import { setupServer } from "msw/node";
import { render, screen, fireEvent } from "@testing-library/react";
import Login from "../Login";const fakeUserRes = { token: "fake_user_token" };
const server = setupServer(rest.post("/api/login", (req, res, ctx) => {return res(ctx.json(fakeUserRes));})
);// 启动服务器
beforeAll(() => server.listen());
// 关闭服务器
afterAll(() => server.close());
// 每个测试用例完成后重置服务器状态
afterEach(() => {server.resetHandlers();window.localStorage.removeItem("token");
});test("测试请求成功", async () => {render(<Login />);fireEvent.change(screen.getByLabelText(/Username/i), {target: { value: "xiejie" },});fireEvent.change(screen.getByLabelText(/Password/i), {target: { value: "123456" },});fireEvent.click(screen.getByText("Submit"));expect(await screen.findByRole("alert")).toHaveTextContent(/Congrats/i);expect(window.localStorage.getItem("token")).toEqual(fakeUserRes.token);
});test("测试请求失败", async () => {server.use(rest.post("/api/login", (req, res, ctx) => {return res(ctx.status(500), ctx.json({ message: "服务器内部出错" }));}));render(<Login />);fireEvent.change(screen.getByLabelText(/Username/i), {target: { value: "xiejie" },});fireEvent.change(screen.getByLabelText(/Password/i), {target: { value: "123456" },});fireEvent.click(screen.getByText("Submit"));expect(await screen.findByRole("alert")).toHaveTextContent(/服务器内部出错/i);expect(window.localStorage.getItem("token")).toBeNull();
});

结论

通过本文的介绍,我们了解了如何使用 Testing Library 和 Jest 对 React 组件进行单元测试。通过对组件的行为进行测试,可以确保组件在不同情况下的表现符合预期,从而提高代码的可靠性和可维护性。

相关文章:

Jest进阶知识:React组件的单元测试

在现代前端开发中&#xff0c;组件是构建应用程序的基本单元。一个组件不仅拥有完整的功能&#xff0c;还能极大地提高代码的复用性。因此&#xff0c;在进行单元测试时&#xff0c;对重要组件进行测试是必不可少的。 Testing Library Testing Library 是一个专门用于测试 We…...

MATLAB——矩阵操作

内容源于b站清风数学建模 数学建模清风老师《MATLAB教程新手入门篇》https://www.bilibili.com/video/BV1dN4y1Q7Kt/ 目录 1.MATLAB中的向量 1.1向量创建方法 1.2向量元素的引用 1.3向量元素修改和删除 2.MATLAB矩阵操作 2.1矩阵创建方法 2.2矩阵元素的引用 2.3矩阵…...

智能数据驱动的风险管理:正大金融科技的创新实践

在不断变化的金融环境中&#xff0c;风险管理成为投资成功的关键因素。正大公司以数据驱动的智能风控体系为核心&#xff0c;通过深度学习、数据分析等技术创新&#xff0c;帮助投资者在复杂的市场条件下实现稳健操作和风险控制。本文将探讨正大如何利用科技手段提升风险管理效…...

贝尔不等式的验证

在量子计算机上运行一个实验&#xff0c;以演示使用Estimator原型违反CHSH不等式。 import numpy as npfrom qiskit import QuantumCircuit from qiskit.circuit import Parameter from qiskit.quantum_info import SparsePauliOpfrom qiskit_ibm_runtime import QiskitRuntim…...

GR2——在大规模视频数据集上预训练且机器人数据上微调,随后预测动作轨迹和视频(含GR1详解)

前言 上个月的24年10.9日&#xff0c;我在朋友圈看到字节发了个机器人大模型GR2&#xff0c;立马去看了下其论文(当然了&#xff0c;本质是个技术报告) 那天之后&#xff0c;我就一直想解读这个GR2来着 然&#xff0c;意外来了&#xff0c;如此文《OmniH2O——通用灵巧且可全…...

伦敦金价格是交易所公布的吗?

今年以来&#xff0c;伦敦金价格波动可谓是波澜壮阔&#xff0c;盘中屡次刷新历史新高&#xff0c;目前已经冲上了2700的历史大关。面对高歌猛进的伦敦金价格&#xff0c;投资者除了进行交易之外&#xff0c;还有一点相关方面的知识是想了解的。例如&#xff0c;伦敦金价格是交…...

Oracle SQL Loader概念及用法

Oracle SQLLoader是Oracle数据库提供的一个高效的数据加载工具&#xff0c;它能够将外部数据&#xff08;如CSV、DAT、Text等文件格式&#xff09;快速加载到Oracle数据库中。以下是对Oracle SQLLoader的详细介绍&#xff1a; 一、主要功能 数据迁移&#xff1a;SQL*Loader常…...

ReactPress 是什么?

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎Star。 ReactPress 是什么&#xff1f; ReactPress 是使用React开发的开源发布平台&#xff0c;用户可以在支持React和MySQL数据库的服务器上架设属于自己的博客、网站。也可以把 ReactP…...

MR30分布式IO模块与高效PLC协同

在现代工业自动化领域中&#xff0c;数据采集与控制系统扮演着至关重要的角色。其中&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;和分布式IO模块&#xff08;Distributed I/O Modules&#xff09;是这一领域的两大核心组件。本文将详细介绍MR30分布式IO模块与PLC如…...

成都睿明智科技有限公司共赴抖音电商蓝海

在这个短视频风起云涌的时代&#xff0c;抖音作为现象级的社交媒体平台&#xff0c;不仅改变了人们的娱乐方式&#xff0c;更悄然间重塑了电商行业的格局。在这片充满机遇与挑战的蓝海中&#xff0c;成都睿明智科技有限公司凭借其敏锐的市场洞察力和专业的服务能力&#xff0c;…...

Android15音频进阶之音频策略加载及使用(九十一)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…...

Spring设值注入

设值注入&#xff08;Setter Injection&#xff09;是Spring框架中依赖注入的一种方式&#xff0c;通过Setter方法将依赖对象注入到目标对象中。设值注入在对象创建后&#xff0c;通过调用Setter方法完成依赖注入。 设值注入的优点 灵活性&#xff1a;设值注入允许在对象创建…...

Spring整合Mybatis过程

配置文件 springConfig --> [jdbcConfig mybatisConfig] jdbc配置文件进行基本的数据库连接池配置 mybatis配置文件进行SqlSessionFactory Bean 和 MapperScannerConfigurer Bean的创建 在Spring容器启动时&#xff0c;系统会根据配置创建并初始化所有MyBatis所需的Bean…...

常见HR问题篇

系列文章目录 第一章 C/C语言篇第二章 计算机网络篇第三章 操作系统篇第四章 数据库MySQL篇第五章 数据库Redis篇第六章 场景题/算法题第七篇 常见HR问题篇 本系列专栏&#xff1a;点击进入 后端开发面经 关注走一波 秋招阶段&#xff0c;面过很多大中小厂&#xff0c;积攒了…...

调用数据集mnist(下载+调用全攻略)

1、下载mnist数据集请自取&#xff1a; 通过百度网盘分享的文件&#xff1a;mnist 链接&#xff1a;https://pan.baidu.com/s/1ia3vFA73hEtWK9qU-O-4iQ?pwdmnis 提取码&#xff1a;mnis 下载后把数据集放在没有中文的路径下。 # 本文将下载好的数据集放在C:\DeepLearning\…...

【基础语法】Java Scanner hasNext() 和 hasNextLine() 的区别

OJ在线编程常见输入输出练习中默认模板 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.…...

react使用Fullcalendar 实战用法

使用步骤请参考&#xff1a;react使用Fullcalendar 卡片式的日历&#xff1a; 需求图&#xff1a; 卡片式的日历&#xff0c;其实我是推荐 antd的&#xff0c;我两个都写了一下都能实现。 antd 的代码&#xff1a; antd的我直接用的官网示例&#xff1a;antd 日历示例 i…...

优秀项目经理必知的10款项目管理软件推荐

本文精心为项目经理推荐30款国内外免费的项目管理软件&#xff0c;涵盖桌面应用与Web平台&#xff0c;其中不乏优秀的开源软件。这些工具旨在助力项目经理高效规划、跟踪与控制项目&#xff0c;无论是通过甘特图进行可视化管理&#xff0c;还是利用任务分配、团队协作等功能&am…...

植物神经紊乱不用怕,这些维生素来帮你!

你是否经常感到身体疲惫、情绪波动大、心悸、胸闷&#xff1f;这可能是植物神经紊乱在作祟。别担心&#xff0c;通过合理的维生素补充&#xff0c;可以有效缓解症状&#xff0c;提升生活质量。今天&#xff0c;我们就来聊聊植物神经紊乱患者应该补充哪些维生素。 &#x1f50d…...

NRF52832学习笔记(41)——添加串口库libuarte

一、背景 由于板子上不支持硬件流控&#xff0c;在使用 app_uart_fifo 库接收串口大数据时&#xff0c;频繁报 APP_UART_COMMUNICATION_ERROR 错误&#xff0c;多次重新初始化后&#xff0c;串口也不再产生中断了。查看官方论坛后决定使用串口异步库 libuarte。 二、简介 Li…...

XGBoost处理缺失值:构建面向天文大数据的极冷矮星智能发现系统

1. 项目概述&#xff1a;当机器学习遇见“暗弱”的宇宙居民在广袤的宇宙中&#xff0c;除了那些明亮耀眼的主序星和星系&#xff0c;还存在着一个庞大而“低调”的群体——极冷矮星。它们涵盖了光谱型晚于M6的恒星&#xff08;如M型矮星&#xff09;以及质量不足以点燃稳定氢聚…...

融合UFF与机器学习势:高通量筛选MOF吸附剂的高效精准方案

1. 项目概述&#xff1a;当经典力场遇上机器学习势&#xff0c;如何实现MOF吸附剂的精准高效筛选&#xff1f;在材料研发的前沿&#xff0c;尤其是像金属-有机框架&#xff08;MOFs&#xff09;这样拥有近乎无限结构可能性的领域&#xff0c;我们常常面临一个“大海捞针”的困境…...

URP Renderer Feature深度解析:生命周期、避坑指南与工业级实现

1. 这不是“加个脚本”就能搞定的渲染扩展——URP Renderer Feature 的真实定位与误用重灾区很多人第一次在URP项目里点开“Renderer Features”面板时&#xff0c;下意识会把它当成“Unity旧版Post-Processing Stack的平替”或者“一个能塞自定义Shader的快捷入口”。我见过太…...

互联网大厂Java面试实录:严肃面试官 vs 求职程序员的三轮技术问答

第一轮&#xff1a;Java基础与核心知识考察面试官&#xff08;严肃&#xff09;: - 请简述Java内存模型中堆和栈的区别&#xff1f; - 你能解释一下JUC包中ReentrantLock的基本用法吗&#xff1f; - 多线程中synchronized和Lock的区别有哪些&#xff1f;程序员&#xff08;稍显…...

TVA光照鲁棒性提升方案

重磅预告&#xff1a;本专栏将独家连载系列丛书《智能体视觉技术与应用》部分精华内容&#xff0c;该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“…...

别再只认ldd了!盘点5种查看Linux程序动态库依赖的方法(含静态/交叉编译场景)

超越ldd&#xff1a;Linux二进制依赖分析的5种专业方法解析在Linux系统管理和开发中&#xff0c;遇到"不是动态可执行文件"的错误提示时&#xff0c;很多工程师的第一反应是困惑——明明是可执行文件&#xff0c;为什么ldd无法识别&#xff1f;这个问题背后隐藏着Lin…...

不用开WPS会员了!这一款电子发票批量打印工具:支持排版 + OCR识别,完全免费!

软件下载 夸克下载&#xff1a;https://pan.quark.cn/s/39d9ed085809 软件介绍 今天给大家带来的是Office的代替品&#xff0c;LibreOffice不用激活、完全免费&#xff0c;非常好用&#xff01; 软件支持Windows、macOS、Linux。它包括包含 Writer&#xff08;文字处理&…...

AI Agent的产品市场契合度验证:寻找高ROI场景的五个核心问题

AI Agent的产品市场契合度验证&#xff1a;寻找高ROI场景的五个核心问题 关键词&#xff1a;AI Agent、产品市场契合度PMF验证、ROI计算框架、Agent适配场景、高价值循环、量化验证、MVP构建 摘要&#xff1a;当AI Agent像“2024年的移动APP”一样成为科技圈新宠时&#xff0c;…...

漏洞研究工作流:从CVE追踪到实战提升的闭环方法论

1. 这不是“资源列表”&#xff0c;而是一套可落地的漏洞研究工作流很多人一看到“在线资源全攻略”就下意识点开收藏&#xff0c;然后扔进浏览器书签夹吃灰。我见过太多安全从业者——包括刚入行的蓝队新人、想补实战短板的渗透测试员、甚至部分做红队支撑的工程师——把CVE编…...

Kali365 设备代码钓鱼攻击机理、危害及防御体系研究

摘要 2026 年 5 月 FBI 发布预警&#xff0c;新型钓鱼即服务平台 Kali365 通过滥用 Microsoft 365 OAuth 2.0 设备代码授权流程&#xff0c;可在不窃取密码、不伪造登录页面的前提下绕过多因素认证&#xff0c;获取长期有效访问令牌&#xff0c;实现账户持久化控制。该平台依托…...