You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:08:21