基于Jest和Enzyme编写StudentGrid组件的滚动测试用例
没问题,我帮你整理好了针对StudentGrid组件的Jest+Enzyme测试用例,刚好覆盖你要求的两个验证点👇
针对StudentGrid组件的Jest+Enzyme测试用例
首先确保你已经安装了必要的依赖:jest、enzyme、对应React版本的Enzyme适配器(比如enzyme-adapter-react-16),如果用TypeScript的话还需要@types/jest和@types/enzyme。另外记得在测试配置文件(比如setupTests.js)里配置Enzyme适配器:
import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; // 替换成你的React版本对应的适配器 configure({ adapter: new Adapter() });
1. 验证滚动事件触发时handleScroll函数被调用
我们通过jest.spyOn监听组件的静态handleScroll方法,然后模拟window滚动事件,断言方法是否被正确调用:
import React from 'react'; import { mount } from 'enzyme'; import StudentGrid from './StudentGrid'; // 替换成你的组件实际路径 describe('StudentGrid scroll event binding', () => { let handleScrollSpy; beforeEach(() => { // 监听组件的静态handleScroll方法 handleScrollSpy = jest.spyOn(StudentGrid, 'handleScroll'); // 提前创建测试需要的DOM元素,避免报错 const mockMainDiv = document.createElement('div'); mockMainDiv.className = 'main'; document.body.appendChild(mockMainDiv); const mockHeader = document.createElement('div'); mockHeader.id = 'student-table-header'; document.body.appendChild(mockHeader); const mockTable = document.createElement('div'); mockTable.id = 'student-table'; document.body.appendChild(mockTable); }); afterEach(() => { // 清理spy和DOM元素,避免测试污染 handleScrollSpy.mockRestore(); document.body.removeChild(document.getElementsByClassName('main')[0]); document.body.removeChild(document.getElementById('student-table-header')); document.body.removeChild(document.getElementById('student-table')); }); it('triggers handleScroll when window scroll event fires', () => { const wrapper = mount(<StudentGrid />); // 模拟window滚动事件 window.dispatchEvent(new Event('scroll')); // 断言handleScroll方法被调用 expect(handleScrollSpy).toHaveBeenCalledTimes(1); wrapper.unmount(); }); });
2. 验证滚动时类名的添加与移除
这个测试需要分两种场景:滚动距离大于等于粘性阈值时添加类名,小于时移除类名。我们会模拟DOM元素的属性值,直接调用handleScroll方法来验证类名变化:
import StudentGrid from './StudentGrid'; // 替换成你的组件实际路径 describe('StudentGrid handleScroll class manipulation', () => { let studentTableHeader; let studentTable; let mainScrollDiv; beforeEach(() => { // 创建测试需要的DOM元素 studentTableHeader = document.createElement('div'); studentTableHeader.id = 'student-table-header'; document.body.appendChild(studentTableHeader); studentTable = document.createElement('div'); studentTable.id = 'student-table'; document.body.appendChild(studentTable); mainScrollDiv = document.createElement('div'); mainScrollDiv.className = 'main'; document.body.appendChild(mainScrollDiv); // 初始化类名状态,确保测试环境干净 studentTableHeader.classList.remove('studentList__sticky'); studentTable.classList.remove('studentList__managetop'); }); afterEach(() => { // 清理DOM元素 document.body.removeChild(studentTableHeader); document.body.removeChild(studentTable); document.body.removeChild(mainScrollDiv); }); it('adds sticky classes when scroll position meets or exceeds the threshold', () => { // 设置滚动距离大于等于header的offsetTop Object.defineProperty(studentTableHeader, 'offsetTop', { value: 100 }); Object.defineProperty(mainScrollDiv, 'scrollTop', { value: 150 }); // 调用静态handleScroll方法 StudentGrid.handleScroll(); // 断言类名已正确添加 expect(studentTableHeader.classList.contains('studentList__sticky')).toBe(true); expect(studentTable.classList.contains('studentList__managetop')).toBe(true); }); it('removes sticky classes when scroll position is below the threshold', () => { // 先手动添加类名,模拟之前滚动过的状态 studentTableHeader.classList.add('studentList__sticky'); studentTable.classList.add('studentList__managetop'); // 设置滚动距离小于header的offsetTop Object.defineProperty(studentTableHeader, 'offsetTop', { value: 100 }); Object.defineProperty(mainScrollDiv, 'scrollTop', { value: 50 }); // 调用静态handleScroll方法 StudentGrid.handleScroll(); // 断言类名已正确移除 expect(studentTableHeader.classList.contains('studentList__sticky')).toBe(false); expect(studentTable.classList.contains('studentList__managetop')).toBe(false); }); });
内容的提问来源于stack exchange,提问作者eupho
相关产品推荐
相关产品推荐

