如何使用Karma Jasmine为Ag Grid的gridApi.forEachNode编写单元测试
解决方案
原有测试的核心问题
- 对
gridApi.forEachNode的监听没有配置执行传入的回调函数,导致内部逻辑永远不会被触发 - 存在类型不匹配问题:你定义的
event.user_id是数字1,而rowNode.data.id是字符串'1',全等判断===会直接不成立,自然不会走到更新逻辑 redrawRows的监听声明时机错误:你在调用被测方法之后才加spy,调用方法时走的是原生实现,spy根本捕获不到调用- 方法名和参数不匹配:你service中定义的方法是
updateGridNode,测试中调用的是updateGridStateAsPerEvent,且多传了无关参数
正确的测试实现
import { GridApi } from '@ag-grid-community/core'; // 其他服务引入省略 it('should update grid data when updateGridNode is called', () => { // 1. 定义mock行数据,注意id类型和后续event的user_id保持一致 const mockRowNodes = [ { data: { id: 1, state: '', status: '' } }, // 匹配event的目标行 { data: { id: 2, state: '', status: '' } } // 不匹配的行,用来校验不会被误修改 ]; // 2. 直接mock GridApi对象,不需要实例化真实的GridApi const mockGridApi = jasmine.createSpyObj<GridApi>('GridApi', ['forEachNode', 'redrawRows']); // 配置forEachNode的mock逻辑,遍历我们自定义的mock行数据,执行传入的回调函数 mockGridApi.forEachNode.and.callFake((callback) => { mockRowNodes.forEach(node => callback(node)); }); // 3. 定义测试用的入参event const testEvent = { user_id: 1, state_id: '1', status: 'SomeStatus' }; // 4. 调用被测方法 service.updateGridNode(testEvent, mockGridApi); // 5. 结果校验 // 校验匹配的行数据被正确更新 expect(mockRowNodes[0].data.state).toBe('1'); expect(mockRowNodes[0].data.status).toBe('SomeStatus'); // 校验不匹配的行数据没有被修改 expect(mockRowNodes[1].data.state).toBe(''); expect(mockRowNodes[1].data.status).toBe(''); // 校验重绘方法被正常调用 expect(mockGridApi.redrawRows).toHaveBeenCalled(); });
如果你的项目用Jest替代了Jasmine,只需要把jasmine.createSpyObj替换为Jest对应的mock语法即可,核心逻辑完全一致。
内容的提问来源于stack exchange,提问作者new coder
相关产品推荐
相关产品推荐

