如何在 Karma 中测试外部 link 导航?

How can I test external link navigation in Karma?

我正在使用 Angular 作为我的框架, 我的应用程序中有一些外部链接。

为了防止用户在有未保存的更改时离开, 我做了一个小技巧,迫使应用程序通过角度 运行, 生命周期,如果 Angular 给出 OK,那么导航应该发生。

看起来像这样:

HTML

<ul class="menu-list list-unstyled">
  <li class="item" *ngFor="let menu of menuList">
    <a (click)="navigate($event, menu.url)" href="{{ menu.url }}">
      {{ menu.name}}
    </a>
  </li>
</ul>

TypeScript

navigate(event: MouseEvent, URL: string): void {
  event.preventDefault(); // Not to navigate through anchor
  this.router.navigate(['/']).then((success) => {
  if (success) {
    window.location.href = URL; // I want to test that this happens
  }
  });
}

到目前为止一切顺利, 但是这个逻辑有点hacky, 所以我想写一个测试来确保它没有被干扰。 这就是事情变得多毛的地方:

it('Should navigate after successful canDeactivate', fakeAsync(() => {
  const uniqueTestURL = 'testURL';
  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();
  const currentURL = window.location.href;
  expect(currentURL).toEqual(uniqueTestURL);
}));

这里是这样写的, Karma 将抛出 404 警告,这不会通过测试:

WARN [web-server]: 404: /testURL
Disconnected (0 times), because no message in 60000 ms.

我也尝试在 karma.js 中设置代理(代理:{'/testURL': ''}),我不会得到 404,但在帐户上测试会失败来自:

Expected 'http://localhost:1234/context.html' to equal 'testURL'

我还尝试将可选参数添加到测试中使用的当前 URL (window.location.href + '?testcase') 但我收到以下错误(即使我将刻度设置为 5000 毫秒):

Expected 'http://localhost:1234/context.html' to equal 'http://localhost:1234/context.html?testCase'.

以及尝试导航到这个 url: 'http://localhost:1234/debug.html' 我知道 karma 有, 但它导致了下一个错误:

 Error: Expected 'http://localhost:1234/context.html' to equal 'http://localhost:1234/debug.html'.

所以我的问题是,我能否以某种方式导航到稍微不同的 URL 然后我的 ChromeHeadles 当前处于打开状态(在测试期间),测试保持 运行ning?

是否有其他方法可以测试 window.location.href 是否已更改?

不要调用 window.location,而是使用 Angular 提供的 Location 服务 - 它基本上是 window.location 的包装器。将其作为依赖项注入构造函数 private location: Location。然后在您的单元测试中为该服务提供一个模拟值,并监视相关方法

使用 Location 进行测试的好例子:

根据您需要的 location 方法,您也可以选择注入 DOCUMENT,然后访问它的 location 属性

import { DOCUMENT } from '@angular/common';
...
constructor(@Inject(DOCUMENT) private document: Document) { }

goToUrl(): void {
    this.document.location.href = 'https://whosebug.com';
}

模拟会很相似