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

Angular2单元测试问题:验证router.navigate调用失败

排查Angular测试中Router Spy未被调用的问题

你遇到的这个测试失败问题,核心原因是mockRouter的初始化时机错误,导致组件实际使用的Router实例并不是你创建的带spy的那个对象。

具体问题分析

看你的beforeEach代码:

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [ AppComponent],
    imports: [FormsModule, HttpClientTestingModule],
    providers: [ { provide: Router, useValue: mockRouter }] // 这里mockRouter还未定义,值为undefined
  });
  fixture = TestBed.createComponent(AppComponent);
  component = fixture.componentInstance;
  mockRouter = { navigate: jasmine.createSpy('navigate') }; // 此时才创建带spy的对象,但已错过注入时机
});

当你配置TestBed时,mockRouter还没有被赋值,此时传入的useValue是undefined。之后你才创建了带有navigate spy的对象,但这个对象并没有被注入到组件里——组件拿到的是之前那个undefined的Router实例,所以调用showProfile时,自然不会触发你期望的spy调用。

修复方案

调整代码顺序,先创建带spy的mockRouter,再配置TestBed,这样TestBed才能把正确的mock对象注入到组件中:

beforeEach(() => {
  // 第一步:先初始化带spy的mockRouter
  mockRouter = { navigate: jasmine.createSpy('navigate') };
  
  // 第二步:用已初始化的mockRouter配置TestBed
  TestBed.configureTestingModule({
    declarations: [ AppComponent],
    imports: [FormsModule, HttpClientTestingModule],
    providers: [ { provide: Router, useValue: mockRouter }]
  });
  
  fixture = TestBed.createComponent(AppComponent);
  component = fixture.componentInstance;
});

修改之后,组件里的router依赖就是你创建的带有spy的mock对象了,调用showProfile(12345)时,navigate spy会被正确触发,测试就能通过。

额外小提示

如果你的导航逻辑涉及异步操作(比如路由守卫),可以用fakeAsync和tick来确保异步操作完成后再断言,但你的当前场景是同步调用navigate,所以不需要额外处理。

内容的提问来源于stack exchange,提问作者Present practice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:32:31