Angular 如何使用 jasmine、karma 测试 window.location.href

Ryo*_*Ryo 5 unit-testing karma-jasmine angular

在 Angular 项目(Angular CLI:9.1.4)中,我有一个具有以下功能的组件:window.location.href = EXTERNAL_URL

a.组件.ts

import { Component, OnInit } from '@angular/core';
import { Service } from 'services/service';

@Component({
  selector: 'a',
  templateUrl: './a.component.html',
  styleUrls: ['./a.component.scss']
})
export class AComponent implements OnInit {
  constructor(private service: Service) {}

  ngOnInit(): void {}

  redirect() {
    window.location.href = 'https://sample.com'
  }
}
Run Code Online (Sandbox Code Playgroud)

对于单元测试,我有 a.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { AComponent } from './A.component';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

describe('#AComponent', () => {
  let component: AComponent;
  let fixture: ComponentFixture<AComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientModule],
      declarations: [AComponent]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

  });

  describe('test', () => {
    it('test redirect function', () => {
      component.redirect();

      expect(window.location.href).toEqual('https://sample.com');
    });
  });
});

Run Code Online (Sandbox Code Playgroud)

它必须检查 URL“window.location.href”是否与我预期的相同。

但是在运行测试时,显示错误:

预期“http://localhost:0987/context.html”等于“https://sample.com”

为什么 window.location.href 参数是这样的?

另外,Karma (v5.0.4) 在浏览器上正常显示测试结果,但在本次测试中,浏览器页面突然发生变化。

在此输入图像描述

发生这种情况是因为“window.location.href”已在测试浏览器上运行(它尝试打开https://sample.com)。但由于这个重定向,我看不到 Karma 结果。

所以,我的问题是

  • 如何测试 window.location.href
  • 如何停止 karma 测试浏览器上的重定向

PS我原以为使用window.location.href不好,但我找不到任何重定向外部URL的方法。

Vik*_*iev 1

这里最大的问题在于窗口对象本身。但我们可以针对测试环境重新定义它。我的解决方案:

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'a',
      templateUrl: './a.component.html',
      styleUrls: ['./a.component.scss']
    })
    export class AComponent {
      private window = window;

      constructor() {}

      redirect() {
        this.window.location.href = 'https://sample.com'
      }
    }
Run Code Online (Sandbox Code Playgroud)

规格:

    import { async, ComponentFixture, TestBed } from '@angular/core/testing';
    
    import { AComponent } from './A.component';
    import { By } from '@angular/platform-browser';
    import { HttpClientModule } from '@angular/common/http';
    
    describe('#AComponent', () => {
      let component: AComponent;
      let fixture: ComponentFixture<AComponent>;
    
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports: [HttpClientModule],
          declarations: [AComponent]
        }).compileComponents();
      }));
    
      beforeEach(() => {
        fixture = TestBed.createComponent(AComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      describe('test', () => {
        it('test redirect function', () => {
          let currentLocation;
          component['window'] = {
            location: {
             set href(value) { currentLocation = value;}
            }
          } as Window & typeof globalThis;

          component.redirect();
    
          expect(currentLocation).toBe('https://sample.com');
        });
      });
    });
Run Code Online (Sandbox Code Playgroud)