如何用sinon.js、mocha、chai为含fromEvent(scroll)的addScroll方法编写单元测试
addScroll 方法单元测试实现
核心测试覆盖点
测试需要验证三个核心逻辑,避免漏测:
- 调用
addScroll后,是否正确在$size对象上注册scroll事件监听 - scroll事件触发时,是否根据
pageYOffset是否大于5,正确更新实例的scroll布尔属性 - 终止信号
unSubs$触发后,是否正确取消订阅,不再响应后续scroll事件
测试代码实现
基于mocha运行器、chai断言库、sinon mock工具的测试代码如下,测试前不需要额外引入jsdom等DOM仿真库,直接mock依赖即可:
const { expect } = require('chai'); const sinon = require('sinon'); const { Subject } = require('rxjs'); // 替换为你项目中待测试类的实际引入路径 const ScrollComponent = require('./your-component-path'); describe('addScroll 方法', () => { let testComponent; let mockScrollContainer; let fireScrollEvent; beforeEach(() => { // 构造mock滚动容器,实现fromEvent依赖的事件注册接口 mockScrollContainer = { pageYOffset: 0, addEventListener: sinon.spy(), removeEventListener: sinon.spy() }; // 捕获scroll事件回调,方便测试时手动触发 fireScrollEvent = null; mockScrollContainer.addEventListener.callsFake((eventName, handler) => { if (eventName === 'scroll') fireScrollEvent = handler; }); // 初始化待测试组件实例,注入mock依赖 testComponent = new ScrollComponent(); testComponent.$size = mockScrollContainer; testComponent.unSubs$ = new Subject(); testComponent.scroll = false; }); afterEach(() => { // 每个用例执行完触发终止信号,清理订阅,避免测试污染 testComponent.unSubs$.next(); testComponent.unSubs$.complete(); sinon.restore(); }); it('调用方法后会成功注册scroll事件监听', () => { testComponent.addScroll(); expect(mockScrollContainer.addEventListener.calledOnceWith('scroll')).to.be.true; }); it('触发scroll事件时,会根据pageYOffset值正确更新scroll属性', () => { testComponent.addScroll(); // 偏移量小于等于5时,scroll应为false mockScrollContainer.pageYOffset = 3; fireScrollEvent(); expect(testComponent.scroll).to.be.false; // 偏移量大于5时,scroll应为true mockScrollContainer.pageYOffset = 6; fireScrollEvent(); expect(testComponent.scroll).to.be.true; // 偏移量回落至5以下时,scroll应同步改回false mockScrollContainer.pageYOffset = 0; fireScrollEvent(); expect(testComponent.scroll).to.be.false; }); it('unSubs$终止信号触发后,不再响应后续scroll事件', () => { testComponent.addScroll(); // 手动触发终止订阅信号 testComponent.unSubs$.next(); // 触发scroll事件,设置偏移量为满足条件的值 mockScrollContainer.pageYOffset = 10; fireScrollEvent(); // scroll属性应保持初始值,不会被更新 expect(testComponent.scroll).to.be.false; // 验证事件监听已被移除 expect(mockScrollContainer.removeEventListener.calledWith('scroll')).to.be.true; }); });
适配提示:如果你使用的RxJS版本中
fromEvent优先通过on/off方法注册事件,只需要把mock对象里的addEventListener/removeEventListener替换为on/off即可,其他逻辑无需调整。
内容的提问来源于stack exchange,提问作者afgomez123
相关产品推荐
相关产品推荐

