我已经为我的一个组件编写了测试用例.它涵盖了整个函数,但抛出了以下错误:

  Disconnected , because no message in 30000 ms.

 Some of your tests did a full page

header.component.ts

import { Component, OnInit } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
  constructor(private cookieService:CookieService) {}

  ngOnInit(): void {}

  logout(): void {
    localStorage.clear();
    sessionStorage.clear();
    let cookie:any = this.cookieService.getAll();
    Object.keys(cookie)?.forEach((res:any) => {
        this.cookieService.delete(res, '/', '', true, 'None');
        document.cookie = `${res}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
    });
    window.location.href ='https://demo.demopreview.com/login/login.htm';
   }
}

header.component.spec.ts

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HeaderComponent } from './header.component';
import { HttpClientModule } from '@angular/common/http';
import { CookieService } from 'ngx-cookie-service';

describe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;
  let cookieService: CookieService;

  const mockWindow = { location: { href: '' } };
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [HeaderComponent],
      imports:[HttpClientModule],
      providers: [
        CookieService,
        { provide: 'Window', useValue: mockWindow }
      ]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(HeaderComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    cookieService = TestBed.inject(CookieService);
  });

  afterEach(() => {
    localStorage.clear();
    sessionStorage.clear();
    document.cookie.split(";").forEach((c) => {
      document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
    });
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should call cookieService.delete for each cookie', () => {
    spyOn(cookieService, 'getAll').and.returnValue({ 'testCookie1': 'value1', 'testCookie2': 'value2' });
    spyOn(cookieService, 'delete');
    component.logout();
    expect(cookieService.delete).toHaveBeenCalledWith('testCookie1', '/', '', true, 'None');
    expect(cookieService.delete).toHaveBeenCalledWith('testCookie2', '/', '', true, 'None');
  });

});

它与任何版本问题无关.因为如果我删除这个测试用例,每个测试用例都会通过.

推荐答案

如果您必须测试涉及直接操作window.location.href的代码,则可能需要采用不同的策略

在AppModule中,将窗口对象作为值提供.这将允许您在任何需要的地方进行注射.

app.module.ts:

@NgModule({        
  providers: [
    { provide: 'Window',  useValue: window }
  ]
})
export class AppModule {}

在您的HeaderComponent中,使用‘Window’标记注入Window对象.不是直接引用窗口对象

header.component.ts

  constructor(private cookieService:CookieService,@Inject('Window') private window: Window ) {}
  
  logout(): void {
    localStorage.clear();
    sessionStorage.clear();
    let cookie:any = this.cookieService.getAll();
    Object.keys(cookie)?.forEach((res:any) => {
        this.cookieService.delete(res, '/', '', true, 'None');
        document.cookie = `${res}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
    });
    this.window.location.href ='https://demo.demopreview.com/login/login.htm';
   }

注销方法是异步的.要在Angular 测试中处理异步代码,应该使用Angular 测试实用程序提供的Async和fakeAsync函数.

header.component.spec.ts

 it('should call cookieService.delete for each cookie', fakeAsync(() => {
    spyOn(cookieService, 'getAll').and.returnValue({ 'testCookie1': 'value1', 'testCookie2': 'value2' });
    spyOn(cookieService, 'delete');
   
    component.logout();

    
    // Simulate the passage of time until all asynchronous activities complete
     tick();

    expect(cookieService.delete).toHaveBeenCalledWith('testCookie1', '/', '', true, 'None');
    expect(cookieService.delete).toHaveBeenCalledWith('testCookie2', '/', '', true, 'None');

  }));

Angular相关问答推荐

如何使用新的@for遍历Angular 为17的对象?

MAT表的内联文本编辑-未刷新编辑图标

在RxJS和ANGING中处理多个API调用

当嵌套在异步容器中时,S会阻止具有动态值的ionic 段工作吗?

bootstrap 可折叠菜单在单击时未展开.Angular 应用程序

Angular 显示来自文字数组的SVG路径

基于RxJS的Angular 服务数据缓存

Angular 15 在 URL 中使用@进行路由

Angular 15 Ref 错误:初始化前无法访问组件 A

根据变量值更改按钮样式

如何为所有模块全局声明指令?

无法读取 angular2 中未定义(…)的属性 push

Angular [disabled]="MyBoolean" 没有工作

Angular 2.0 中 $scope 的替代品

如何在不刷新整页的情况下更新组件

如何组合两个可观察到的结果?

Angular2material对话框自动关闭

我应该在 Angular 4+ 应用程序中 for each 组件创建一个模块吗?

如何在 Angular 2 中动态添加和删除表单字段

从 Angular 中的自定义表单组件访问 FormControl