news 2026/4/19 21:33:35

React-Resizable 测试驱动开发:Jest单元测试与快照测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
React-Resizable 测试驱动开发:Jest单元测试与快照测试

React-Resizable 测试驱动开发:Jest单元测试与快照测试

【免费下载链接】react-resizableA simple React component that is resizable with a handle.项目地址: https://gitcode.com/gh_mirrors/re/react-resizable

React-Resizable 是一个简单的 React 组件,允许用户通过拖动手柄调整元素大小。本文将深入探讨如何使用 Jest 和 React Testing Library 为 React-Resizable 组件构建全面的测试套件,包括单元测试和快照测试,确保组件在各种场景下的可靠性和稳定性。

测试环境搭建

React-Resizable 项目采用 Jest 作为测试运行器,配合 React Testing Library 进行组件测试。项目的测试文件主要集中在__tests__目录下,包括Resizable.test.jsResizableBox.test.js两个核心测试文件。

要开始测试,首先需要克隆项目仓库:

git clone https://gitcode.com/gh_mirrors/re/react-resizable cd react-resizable npm install npm test

单元测试策略

React-Resizable 的单元测试覆盖了组件的各种功能和边界情况,主要包括以下几个方面:

组件渲染测试

基础渲染测试确保组件能够正确渲染并应用指定的属性。例如,在Resizable.test.js中,测试验证组件是否正确应用了className属性,并渲染了指定的子元素:

test('with correct props', () => { const {container} = render(<Resizable {...props}>{resizableBoxChildren}</Resizable>); // 检查类名和子元素是否存在 expect(container.querySelector('.test-classname')).toBeInTheDocument(); expect(container.querySelector('.test-classname .children')).toBeInTheDocument(); });

调整手柄测试

调整手柄是 Resizable 组件的核心功能,测试覆盖了不同类型手柄的渲染和交互:

  • 默认手柄:验证东南(se)和东(e)等默认手柄的渲染
  • 自定义手柄:测试通过函数或组件自定义手柄的场景
  • 手柄数量:确保渲染的手柄数量与配置一致
test('renders all specified handles', () => { const allHandles = ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw']; const {container} = render( <Resizable {...props} resizeHandles={allHandles}> {resizableBoxChildren} </Resizable> ); allHandles.forEach(handle => { expect(container.querySelector(`.react-resizable-handle-${handle}`)).toBeInTheDocument(); }); });

尺寸约束测试

测试验证组件是否遵守最小和最大尺寸约束:

test('minConstraints prevents sizing below minimum', () => { // 尝试将尺寸调整到小于最小值 seHandler(mockEvent, { node, deltaX: -40, deltaY: -40 }); // 验证尺寸被约束在最小值 expect(props.onResize).toHaveBeenLastCalledWith( mockEvent, expect.objectContaining({ size: { width: 30, // 被约束到最小值 height: 30, // 被约束到最小值 }, }) ); });

轴向限制测试

测试验证组件在不同轴向设置下的行为:

  • axis="x":只允许水平调整
  • axis="y":只允许垂直调整
  • axis="none":完全禁用调整
test('axis="x" only allows horizontal resizing', () => { // 尝试同时调整宽度和高度 seHandler(mockEvent, { node, deltaX: 10, deltaY: 20 }); // 验证只有宽度变化,高度保持不变 expect(props.onResize).toHaveBeenLastCalledWith( mockEvent, expect.objectContaining({ size: { width: 60, // 变化 height: 50, // 不变 }, }) ); });

快照测试实践

快照测试是确保 UI 一致性的有效方法,React-Resizable 项目广泛使用快照测试来捕获组件的渲染状态。

基础快照测试

Resizable.test.jsResizableBox.test.js中,都包含了基础快照测试:

test('snapshot default props', () => { const {container} = render(<Resizable {...props}>{resizableBoxChildren}</Resizable>); expect(container.firstChild).toMatchSnapshot(); });

快照文件存储在__tests__/__snapshots__目录下,如Resizable.test.js.snapResizableBox.test.js.snap

快照更新策略

当组件的预期外观发生变化时,需要更新快照:

npm test -- -u

这将更新所有过时的快照,确保测试与最新的组件渲染结果保持一致。

事件处理测试

React-Resizable 组件提供了丰富的事件回调,测试确保这些回调被正确触发并传递预期参数:

调整事件测试

测试验证onResizeonResizeStartonResizeStop回调的触发:

test('onResizeStop reports correct size', () => { // 模拟调整开始 startHandler(mockEvent, { node, deltaX: 0, deltaY: 0 }); // 模拟拖动调整 dragHandler(mockEvent, { node, deltaX: 10, deltaY: 10 }); // 模拟调整停止 stopHandler(mockEvent, { node, deltaX: 0, deltaY: 0 }); // 验证 onResizeStop 被调用并传递正确的尺寸 expect(onResizeStop).toHaveBeenCalledWith( mockEvent, expect.objectContaining({ size: { width: 60, height: 60 }, handle: 'se', }) ); });

事件持久化测试

测试确保事件对象在需要时被正确持久化:

test('calls event.persist when available', () => { const mockEvent = { persist: jest.fn() }; startHandler(mockEvent, { node, deltaX: 0, deltaY: 0 }); expect(mockEvent.persist).toHaveBeenCalled(); });

高级测试场景

缩放变换测试

当组件应用了 CSS 变换(如缩放)时,测试确保调整行为仍然正确:

test('use of < 1 transformScale', () => { render( <Resizable {...customProps} transformScale={0.5} ref={resizableRef}> {resizableBoxChildren} </Resizable> ); // 验证缩放变换下的尺寸计算 expect(props.onResize).toHaveBeenLastCalledWith( mockEvent, expect.objectContaining({ size: { height: 30, // 缩放后计算的正确高度 width: 40, // 缩放后计算的正确宽度 }, }) ); });

宽高比锁定测试

测试验证当锁定宽高比时,组件是否保持正确的比例:

test('lockAspectRatio preserves aspect ratio', () => { render( <Resizable {...customProps} lockAspectRatio={true} ref={resizableRef}> {resizableBoxChildren} </Resizable> ); // 尝试非等比例调整 seHandler(mockEvent, { node, deltaX: 10, deltaY: 5 }); // 验证尺寸保持等比例 expect(props.onResize).toHaveBeenLastCalledWith( mockEvent, expect.objectContaining({ size: { height: 60, // 取较大的变化值 width: 60, // 取较大的变化值 }, }) ); });

测试最佳实践

测试组织

React-Resizable 的测试采用清晰的层次结构,使用describe块组织相关测试,使测试套件易于维护:

describe('render Resizable', () => { describe('Handles', () => { test('with handle function', () => { ... }); test('with handle component', () => { ... }); }); describe('axis restrictions', () => { test('axis="x" only allows horizontal resizing', () => { ... }); test('axis="y" only allows vertical resizing', () => { ... }); }); // 更多测试组... });

模拟与清理

每个测试前都会清理模拟函数,确保测试之间的独立性:

beforeEach(() => { jest.clearAllMocks(); });

真实 DOM 交互

使用 React Testing Library 的renderact确保测试模拟真实用户交互:

act(() => { boxRef.current.onResize(fakeEvent, data); });

总结

通过 Jest 和 React Testing Library,React-Resizable 项目构建了全面的测试套件,覆盖了组件的各种功能和边界情况。单元测试确保了组件的核心功能正常工作,而快照测试则保障了 UI 的一致性。这种测试驱动的开发方式不仅提高了代码质量,也为后续维护和扩展提供了信心。

无论是处理调整手柄、尺寸约束,还是处理各种事件回调,完善的测试 coverage 确保了 React-Resizable 组件在各种使用场景下的可靠性和稳定性。对于希望为自己的 React 组件构建测试套件的开发者来说,React-Resizable 的测试策略提供了一个优秀的参考范例。

【免费下载链接】react-resizableA simple React component that is resizable with a handle.项目地址: https://gitcode.com/gh_mirrors/re/react-resizable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 23:47:40

利用OBS打造高效虚拟摄像头:从编译到实战

1. 虚拟摄像头&#xff1a;从概念到应用场景 想象一下这样的场景&#xff1a;你正在准备一场重要的线上会议&#xff0c;但电脑自带的摄像头画质太差&#xff1b;或者你需要同时向多个平台直播&#xff0c;却苦于摄像头只能被一个程序独占。这时候&#xff0c;虚拟摄像头技术就…

作者头像 李华
网站建设 2026/4/15 13:09:47

Rust的闭包语法糖

Rust的闭包语法糖&#xff1a;简洁与灵活的完美结合 在Rust中&#xff0c;闭包是一种可以捕获环境变量的匿名函数&#xff0c;其语法糖设计既简洁又强大&#xff0c;让代码更易读且高效。闭包不仅能像普通函数一样传递和使用&#xff0c;还能根据上下文自动推断参数和返回类型…

作者头像 李华
网站建设 2026/4/16 15:00:43

Java的java.lang.invoke.VarHandle内存访问与原子操作在并发中的精细控制

Java并发编程中的精细控制&#xff1a;VarHandle的威力 在现代高并发应用中&#xff0c;精确的内存访问与原子操作是确保线程安全的关键。Java 9引入的java.lang.invoke.VarHandle为开发者提供了比传统synchronized或AtomicXXX类更灵活的低级别内存控制能力。它允许直接操作变…

作者头像 李华
网站建设 2026/4/16 22:23:15

Liquor v1.4.0 深度解析:Java 动态编译如何实现运行时高效执行?

1. Liquor框架&#xff1a;Java动态编译的新选择 第一次听说Liquor框架时&#xff0c;我正在为一个电商项目开发动态规则引擎。当时需要实时编译用户提交的优惠券计算规则&#xff0c;试过JDK自带的JavaCompiler API&#xff0c;那体验简直让人崩溃 - 繁琐的API调用、晦涩的错误…

作者头像 李华
网站建设 2026/4/15 19:15:22

从0到1构建AI驱动的前端工程化平台:基于OpenTiny NEXT的实战复盘

文章目录每日一句正能量前言&#xff1a;当AI成为工程化的一环一、背景&#xff1a;传统工程化的瓶颈1.1 我们的技术债务图谱1.2 为什么选择OpenTiny NEXT&#xff1f;二、实战一&#xff1a;MCP协议在CI/CD中的落地2.1 场景定义&#xff1a;智能代码审查2.2 架构设计&#xff…

作者头像 李华