Angular单元测试调用fixture.detectChanges()报无法读取null的'params'属性
问题排查与解决
根因说明
报错Cannot read properties of null (reading 'params')的直接原因是组件代码中调用this.route.parent.params时,route.parent为null。
你使用了RouterTestingModule但没有为测试环境mock父路由的ActivatedRoute实例,默认测试环境下ActivatedRoute没有parent属性。不调用fixture.detectChanges()时,组件的初始化生命周期钩子(如ngOnInit)不会执行,gettingLowBlowId方法未被触发,所以不会报错;调用fixture.detectChanges()后触发生命周期执行对应方法,就会抛出空指针异常。
解决方案
你需要在测试配置中手动mock带parent参数的ActivatedRoute,操作步骤如下:
1. 导入依赖
在测试文件头部导入对应依赖:
import { ActivatedRoute } from '@angular/router'; import { of } from 'rxjs';
2. 新增ActivatedRoute mock配置
修改TestBed的providers数组,新增ActivatedRoute的mock项:
providers: [ {provide: AdnimistrationSiteService, useValue: administrationServiceMock}, {provide: VisualisationFileStorageManagerService, useValue: visualisationFileStorageManagerServiceMock}, // 新增以下配置 { provide: ActivatedRoute, useValue: { parent: { params: of({ blower_id: 'test_blower_id' }) // 可自定义测试需要的路由参数值 } } } ],
3. 可选:动态修改路由参数
如果不同测试用例需要不同的blower_id参数,可以在测试用例内动态修改:
it("Should display current blower that user is at the moment in span", () => { const route = TestBed.inject(ActivatedRoute); spyOn(route.parent, 'params').and.returnValue(of({ blower_id: 'custom_id' })); fixture.detectChanges(); const spanEle = fixture.debugElement.query(By.css(".headerh3 span")); expect(spanEle.nativeElement.textContent).toBe("custom_id"); })
额外优化建议
- 测试用例中校验innerHTML匹配
_ngcontent-a-c391属性的逻辑不稳定,Angular的样式隔离哈希值每次编译都会变化,建议只校验文本内容,不要匹配带哈希的属性。 - 组件内的
gettingLowBlowId方法加了async关键字但内部没有await操作,该async关键字多余,可删除避免异步逻辑干扰测试。
内容的提问来源于stack exchange,提问作者david1997997
相关产品推荐
相关产品推荐

