Angular ng-mocks单元测试报错:TypeError: Cannot read 'pipe' of undefined
问题描述
我正在开发一个Nx Angular项目,使用Jasmine Karma结合ng-mocks库编写单元测试,参考项目内已有示例但仍无法运行,报错信息为TypeError: Cannot read properties of undefined (reading 'pipe')。
报错出现在组件ngOnInit生命周期钩子的如下代码处:
ngOnInit(){ this.subscriptions.push(this.router.events.pipe(filter(event => event instanceof NavigationEnd)) .subscribe(() => this.setPageData())); this.setPageData() this.createButtons(); }
我的单元测试代码如下:
describe('DepartmentEditorComponent', () => { MockInstance.scope(); beforeEach(() => MockBuilder([DepartmentEditorPerspectiveComponent, TranslateModule.forRoot(), NoopAnimationsModule, HttpClientModule, HttpClientTestingModule], [DepartmentPerspectiveModule, AreasDataMaintenanceModule, RouterModule.forRoot([]), DepartmentDataService]) .keep(CommonModule) .keep(FormBuilder) .keep(ReactiveFormsModule), ); it('should create', () => { const fixture = MockRender(DepartmentEditorPerspectiveComponent); expect(fixture.point.componentInstance).toBeDefined(); }); });
我尝试添加可能缺失的模块,但报错仍存在,推测需要在测试中处理Observable,但不清楚如何使用ng-mocks语法实现。
解决方案
报错核心是组件依赖的Router实例未被正确mock,导致this.router.events为undefined。用ng-mocks可以通过以下方式解决:
修改后的测试代码
import { Router, NavigationEnd } from '@angular/router'; import { of } from 'rxjs'; import { MockInstance, MockBuilder, MockRender } from 'ng-mocks'; describe('DepartmentEditorComponent', () => { MockInstance.scope(); beforeEach(() => { // Mock Router的events属性,返回包含NavigationEnd事件的Observable MockInstance(Router, 'events', of(new NavigationEnd(1, '/', '/'))); return MockBuilder(DepartmentEditorPerspectiveComponent) .keep(TranslateModule.forRoot()) .keep(NoopAnimationsModule) .keep(HttpClientTestingModule) .keep(CommonModule) .keep(FormBuilder) .keep(ReactiveFormsModule) .mock(DepartmentPerspectiveModule) .mock(AreasDataMaintenanceModule) .mock(DepartmentDataService); }); it('should create', () => { const fixture = MockRender(DepartmentEditorPerspectiveComponent); expect(fixture.point.componentInstance).toBeDefined(); }); });
关键修改说明
- 用
MockInstance(Router, 'events', of(...))直接mock Router的events属性,给它返回一个合法的Observable,解决pipe()调用时的undefined报错 - 简化
MockBuilder写法:直接传入目标组件,用.mock()处理依赖的模块和服务,避免冗余的模块导入 - 移除
HttpClientModule,保留测试专用的HttpClientTestingModule,避免模块冲突
如果不需要模拟真实导航事件,也可以返回空Observable:
MockInstance(Router, 'events', of());
内容的提问来源于stack exchange,提问作者AillaEww
相关产品推荐
相关产品推荐

