Angular单元测试中点击按钮后ng-template未触发渲染问题
问题修复方案
你遇到的报错由以下几个错误共同导致,按顺序修复即可让ng-template正常渲染:
错误1:模板和组件变量名不匹配
组件component.ts的showEditableData方法中修改的变量是editable,但模板*ngIf判断的变量是editing,二者名称不对应,点击按钮后渲染条件永远不成立。
错误2:单元测试元素查询逻辑错误
你在测试初始就执行了fixture.debugElement.query()将查询结果缓存,这个结果是查询执行时刻的DOM快照,后续DOM更新后不会自动刷新,所以永远会返回初始状态的null。需要在每次判断DOM状态时重新执行查询。
错误3:变更检测执行顺序错误
你在初始查询元素之后才调用fixture.detectChanges()触发首次渲染,初始查询拿到的永远是空值。
修复后的component.ts代码
showEditableData(){ // 变量名和模板保持一致 this.editing = true; }
修复后的单元测试代码
it('should enable editing form', () => { // 先触发首次渲染 fixture.detectChanges(); // 初始状态校验,每次判断都重新查询DOM expect(fixture.debugElement.query(By.css('.static-data-container'))).toBeTruthy(); expect(fixture.debugElement.query(By.css('.editable-data-container'))).toBeFalsy(); // 触发编辑按钮点击 const buttonEdit = fixture.debugElement.query(By.css('.edit-button')); buttonEdit.triggerEventHandler('click', null); // 点击后触发变更检测更新DOM fixture.detectChanges(); // 校验最终状态 expect(fixture.debugElement.query(By.css('.editable-data-container'))).toBeTruthy(); expect(component.editing).toBeTrue(); });
如果你的业务逻辑包含异步操作,只需要给测试用例包裹fakeAsync,并在点击后调用tick()处理异步队列即可,不需要调用fixture.whenStable()。
内容的提问来源于stack exchange,提问作者Mai Ibraheem
相关产品推荐
相关产品推荐

