如何在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上下文:
- 先注入
DOCUMENT令牌
import { DOCUMENT } from '@angular/common'; import { Inject } from '@angular/core'; // 组件构造函数里注入 constructor(@Inject(DOCUMENT) private document: Document) {}
- 跳转逻辑改为用注入的document对象
navigate(event: MouseEvent, URL: string): void { event.preventDefault(); this.router.navigate(['/']).then((success) => { if (success) { this.document.defaultView.location.href = URL; } }); }
- 测试时直接mock注入的DOCUMENT即可,不需要修改全局window属性,测试隔离性更好。
内容的提问来源于stack exchange,提问作者Efim Rozovsky
相关产品推荐
相关产品推荐

