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

Angular Karma测试router.navigate后重载页面报then未定义问题

报错原因

你碰到的Cannot read property of undefined (reading then )错误根源很明确:

  • 通过jasmine.createSpy创建的navigate方法间谍默认没有配置返回值,调用后会直接返回undefined
  • 业务代码里需要链式调用navigate()返回值的.then()方法,对undefined读取then属性就会触发这个类型错误
  • 你当前写的测试逻辑本身也有问题:手动调用spy对象的navigate方法完全不会走到你真实的业务代码里,等于没测目标逻辑。
正确单元测试编写方式

核心要做三件事:给Router的navigate方法配置符合预期的Promise返回值、拦截window.location.reload避免真的刷新页面、触发真实业务逻辑后校验两个行为是否符合预期。
完整示例代码如下:

import { Router } from '@angular/router';
import { fakeAsync, flush, TestBed } from '@angular/core/testing';
import { YourTargetComponent } from './your-target.component';

describe('路由跳转刷新逻辑测试', () => {
  let routerSpy: jasmine.SpyObj<Router>;
  let reloadSpy: jasmine.Spy;

  beforeEach(async () => {
    // 预置Router间谍,navigate方法返回成功状态的Promise
    routerSpy = jasmine.createSpyObj('Router', ['navigate']);
    routerSpy.navigate.and.resolveTo(true); // 关键配置,解决then方法不存在的问题

    // 拦截reload方法,避免测试时触发真实页面刷新
    reloadSpy = jasmine.createSpy('reload');
    Object.defineProperty(window.location, 'reload', {
      configurable: true,
      value: reloadSpy
    });

    await TestBed.configureTestingModule({
      declarations: [YourTargetComponent],
      providers: [
        { provide: Router, useValue: routerSpy }
      ]
    }).compileComponents();
  });

  it('跳转test路由成功后应当触发页面刷新', fakeAsync(() => {
    // 触发组件中包含目标逻辑的方法,比如你写在组件里的跳转方法
    const fixture = TestBed.createComponent(YourTargetComponent);
    const component = fixture.componentInstance;
    component.triggerNavigation(); // 这个方法里包含this.router.navigate(['test']).then(...)的逻辑

    // 清空微任务队列,等待Promise的then回调执行
    flush();

    // 校验路由跳转参数是否正确
    expect(routerSpy.navigate).toHaveBeenCalledOnceWith(['test']);
    // 校验页面刷新逻辑是否被调用
    expect(reloadSpy).toHaveBeenCalledTimes(1);
  }));
});

几个注意点:

  • 涉及Promise异步逻辑,优先用fakeAsync配合flush()控制异步时序,避免断言执行时回调还没跑导致的测试误判
  • 不要手动调用spy对象的方法,必须通过触发组件/服务自身的业务入口来执行代码,才能覆盖到真实的业务逻辑
  • 配置window.location.reload的属性时记得加configurable: true,方便后续其他用例需要时可以重新修改属性

内容的提问来源于stack exchange,提问作者Sowmiya C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:18:14