WordPress建站经验,做网站公司在丹麦,wordpress首页调用文章,谷歌广告代理商在现代前端开发中#xff0c;组件是构建应用程序的基本单元。一个组件不仅拥有完整的功能#xff0c;还能极大地提高代码的复用性。因此#xff0c;在进行单元测试时#xff0c;对重要组件进行测试是必不可少的。
Testing Library
Testing Library 是一个专门用于测试 We…在现代前端开发中组件是构建应用程序的基本单元。一个组件不仅拥有完整的功能还能极大地提高代码的复用性。因此在进行单元测试时对重要组件进行测试是必不可少的。
Testing Library
Testing Library 是一个专门用于测试 Web 组件的工具库其设计理念是“测试组件的行为而不是实现细节”。通过 Testing Library 提供的一系列 API可以模拟浏览器中的用户交互方式使测试更加贴近真实使用场景。
Jest 与 Testing Library 的关系
Jest一个完整的测试框架提供了匹配器、mock 库、断言工具等旨在提供一个全面的测试工具链。Testing Library一个测试工具库专注于测试组件的行为。它可以与各种框架结合使用提供了一组用于测试 React 组件的工具如 render、screen 和 fireEvent 等。
常用的 Testing Library 扩展库
testing-library/react提供了一组用于测试 React 组件的工具如 render、screen 和 fireEvent。testing-library/jest-dom提供了一组 Jest 断言方法用于测试 DOM 元素的状态和行为如 toBeInTheDocument、toHaveTextContent 等。testing-library/user-event提供了一组用于模拟用户行为的工具如 type、click 和 tab 等。
核心 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 (divlabel htmlFortoggle显示信息/labelinputtypecheckboxnametoggleidtogglechecked{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 (divform onSubmit{handleSubmit}divlabel htmlForusernameInputUsername/labelinput idusernameInput //divdivlabel htmlForpasswordInputPassword/labelinput idpasswordInput typepassword //divbutton typesubmitSubmit{state.loading ? ... : null}/button/form{state.error ? div rolealert{state.error}/div : null}{state.resolved ? (div rolealertCongrats! Youre 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 组件进行单元测试。通过对组件的行为进行测试可以确保组件在不同情况下的表现符合预期从而提高代码的可靠性和可维护性。