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

Jest测试Angular路由时如何Mock document.location.href?

解决Angular Jest测试中document.location.href始终为localhost的问题

你的测试代码只是手动触发了Router的NavigationEnd事件,但Angular的Router事件本身不会直接修改document.location.href——尤其是在测试环境中,Router被Spy后并没有执行实际的导航逻辑,自然不会更新浏览器地址。要解决这个问题,可以通过以下两种方式处理:

方式一:直接Mock document.location.href

在Jest中,document.location.href是只读属性,需要通过Object.defineProperty来修改它的取值:

describe('track Routing Angular ', () => {
    let routerSpy: SpyObject<Router>;
    beforeEach(() => {
      routerSpy = spectator.inject(Router);
      // 重置mock的location.href
      Object.defineProperty(document, 'location', {
        writable: true,
        value: { href: 'http://localhost/' }
      });
    });
    it('should change document location href', () => {
      const fullRouteUrl = 'http://localhost/newPath'; // 必须使用完整URL,href存储的是完整路径
      const event = new NavigationEnd(1, '', fullRouteUrl);
      
      // 触发Router事件(如果你的业务逻辑监听了该事件并修改地址,这里会触发对应逻辑)
      (routerSpy.events as Subject<unknown>).next(event);
      
      // 若业务逻辑未自动修改href,可手动模拟修改后断言
      Object.defineProperty(document, 'location', {
        value: { href: fullRouteUrl }
      });
      
      expect(document.location.href).toBe(fullRouteUrl);
    });
  });

方式二:使用RouterTestingModule进行真实导航测试

如果需要验证Router导航实际会修改地址,可以配置RouterTestingModule,让Router执行真实的导航逻辑(测试环境中会模拟location变化):

import { RouterTestingModule } from '@angular/router/testing';
import { Spectator, createComponentFactory } from '@ngneat/spectator';

// 先定义一个用于测试的空组件
@Component({ template: '' })
class DummyComponent {}

describe('track Routing Angular ', () => {
    let spectator: Spectator<YourTargetComponent>;
    let router: Router;

    const createComponent = createComponentFactory({
      component: YourTargetComponent,
      imports: [
        RouterTestingModule.withRoutes([
          { path: 'newPath', component: DummyComponent } // 配置测试路由
        ])
      ]
    });

    beforeEach(() => {
      spectator = createComponent();
      router = spectator.inject(Router);
    });

    it('should change document location href', async () => {
      await router.navigate(['/newPath']);
      // 断言完整URL路径
      expect(document.location.href).toBe('http://localhost/newPath');
    });
  });

关键注意点:

  • document.location.href始终存储的是完整URL,不能直接断言相对路径newPath,必须使用包含域名的完整路径。
  • 如果你的业务逻辑是通过监听Router事件来修改地址,要确保对应的监听逻辑已正确初始化并订阅了Router的events流。

内容的提问来源于stack exchange,提问作者Isabel C-L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:35:21