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

如何在Karma中测试Angular应用的外部链接跳转逻辑

问题1解答:ChromeHeadless跳转不中断测试是不可行的

Karma的所有测试逻辑都运行在http://localhost:xxxx/context.html这个页面的上下文内,一旦执行window.location.href赋值触发页面跳转,原页面里加载的测试脚本、和Karma服务的连接都会直接销毁,测试进程必然中断,不可能在跳转后继续执行断言逻辑,所以这条路走不通。

问题2解答:通过Mockwindow.location.href的setter实现测试

你不需要真的触发跳转,只需要验证代码执行到了给window.location.href赋值的逻辑、且传入了正确的URL即可,测试时用Jasmine的Spy监控window.location.href的写入行为就行。

修改后的测试用例代码

it('Should navigate after successful canDeactivate', fakeAsync(() => {
  const uniqueTestURL = 'testURL';
  // 给window.location.href的setter打spy,不实际执行跳转
  const locationSpy = spyOnProperty(window.location, 'href', 'set');

  component.menuList = [
  {
    id: 'test',
    name: 'testRoute',
    url: uniqueTestURL,
  }];
  fixture.detectChanges();
  const navigationItem = fixture.debugElement.query(By.css(`.menu-list .item a`));
  navigationItem.nativeElement.click();
  tick();

  // 断言href的setter被调用,且传入了正确的URL
  expect(locationSpy).toHaveBeenCalledOnceWith(uniqueTestURL);
}));

可选优化:业务代码可测性增强

如果想要避免测试时直接操作全局window对象,业务代码可以采用Angular依赖注入的方式引入DOM上下文:

  1. 先注入DOCUMENT令牌
import { DOCUMENT } from '@angular/common';
import { Inject } from '@angular/core';

// 组件构造函数里注入
constructor(@Inject(DOCUMENT) private document: Document) {}
  1. 跳转逻辑改为用注入的document对象
navigate(event: MouseEvent, URL: string): void {
  event.preventDefault();
  this.router.navigate(['/']).then((success) => {
  if (success) {
    this.document.defaultView.location.href = URL;
  }
  });
}
  1. 测试时直接mock注入的DOCUMENT即可,不需要修改全局window属性,测试隔离性更好。

内容的提问来源于stack exchange,提问作者Efim Rozovsky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:36:00