如何测试Angular 2错误Handler实现



我已经覆盖了 @angular/core errorhandler,我正在尝试对其进行测试,但是我会遇到错误。该服务正常工作,但测试失败了。

exception handler.service.ts

import { Injectable, ErrorHandler, forwardRef, Inject } from '@angular/core';
import { BkHttp } from './http.service';
@Injectable()
export class BkExceptionHandlerService implements ErrorHandler {
  constructor( private bkHttp: BkHttp) { }
  handleError(error) {
    let originalError = this.controlError(error);
    this.sendToConsole(originalError);
    this.sendToBitacora( originalError );
    throw( error );

  }
  controlError(error: any): any {
    let originalError: Object =  this.findOriginalError( error );
    return originalError;
  }
  findOriginalError( error: any ) : any {
    while ( error && error.originalError ) {
        error = error.originalError;
    }
    return( error );
  }

  getPrueba():string {
    return 'prueba!!!';
  }
  sendToConsole(error:any): void {
    try {
      console.group( 'START ErrorHandler' );
      console.error( error );
      console.error( error.message );
      console.error( error.stack );
      console.groupEnd();
    } catch (handlingError) {
      console.group( 'START ErrorHandler' );
      console.warn( 'Error when trying to output error. Pure Irony' );
      console.error( handlingError );
      console.groupEnd();
    }
  }
  sendToBitacora(error:any): void {
    let body: Object = {
      name: error.name,
      message: error.message,
      stack: error.stack,
      location: window.location.href
    };

    this.bkHttp.post('http://google.es', body).subscribe(res => { });
    //this.bkHttp.post('http://fgooffglffffe.es', body);


  }
}

这里是测试文件

import { Component, DebugElement } from '@angular/core';
import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import { By }           from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { Response, Http } from '@angular/http';
import { BkHttp } from './http.service';
import { BkExceptionHandlerService }  from './exception-handler.service';
const ERROR_MESSAGE = 'Dummy Error';
@Component({
  selector: 'dummy-component',
  template: `<button (click)="throwError()">Throw an error!!!</button>`
})
export class MockComponent {
  public throwError(): void {
    throw Error(ERROR_MESSAGE);
  }
}

describe('FancyService without the TestBed', () => {
  let bkExceptionHandlerService: BkExceptionHandlerService;
  let bkHttp: BkHttp;
  let fixture: ComponentFixture<MockComponent>;
  let loggerSpy: jasmine.Spy;
  let consoleSpy: jasmine.Spy;
  let errorObservableSpy: jasmine.Spy;
  let comp: MockComponent;

beforeEach( async(() => {
        TestBed.configureTestingModule({
          declarations: [ MockComponent ],
        })
        .compileComponents(); // compile template and css
      }));
  beforeEach(() => {
    bkExceptionHandlerService = new BkExceptionHandlerService(bkHttp);
    loggerSpy  = spyOn(bkExceptionHandlerService, 'controlError').and.callThrough();
    consoleSpy = spyOn(console, 'error');
    errorObservableSpy = jasmine.createSpy('log event observable subscription');
    fixture = TestBed.createComponent(MockComponent);
    comp = fixture.componentInstance;
    fixture = TestBed.createComponent(MockComponent);
  });
  it('should log error to the console', () => {
      let elem = fixture.debugElement.query(By.css('button'));
      elem.triggerEventHandler('click', null);
      expect(loggerSpy).toHaveBeenCalledWith(jasmine.any(Error), ERROR_MESSAGE);
  });
});

最后,错误

Error: Error in ./MockComponent class MockComponent - inline template:0:0 caused by: Dummy Error in node_modules/@bankular/development-tools/config/karma-test-shim.js (line 49231)

你们能帮我吗?

我遇到了测试一个同样实现errorhandler的类,并且与您相同的路径(但是就我而言,在我的情况下,一个模拟服务引发了错误)并运行了进入同一测试的问题,迫使测试失败。这是一本教科书的示例,需要重构以使某些东西更具测试。

它也打了我,我不仅要测试我的 handleRor()的实现,还可以测试Angular2的ErrorHandler功能。换句话说,测试的集成级别是较高的,我只需要测试我的 errorHandlerService 服务与Angular2的错误功能隔离。

这就是我所做的

@Injectable()
export class ErrorHandlerService implements ErrorHandler {
  constructor() {}
  handleError(error: any): void {
    this.processError(error);
    throw error;
  }
  public processError(error: any) {
    console.log(error);
  }
}

和测试本身

  it('correctly handles error', inject([ErrorHandlerService], (service: ErrorHandlerService) => {
    const spy = spyOn(console, 'log');
    const error: Error = new Error('ERROR');
    service.processError(error);
    expect(spy).toHaveBeenCalledWith(error);
  }));

您不需要实际throw new Error(),Angular2团队已经为您确认。

我建议两个不同的测试方案:

您进行" bkexceptionHandlerService"的实际单元测试,呼叫" thanderror"方法直接,间谍和嘲笑您需要涵盖所有方案的方法。

和一项集成测试,您实际上覆盖了" errorhandler"的提供商。使用您的自定义" BkexceptionHandlerService"然后,您检查一下当您尝试注入" errorhandler"实例时,它会返回您的" bkexceptionhandlerservice"的实例"

例如(从此处启发https://github.com/angular/angular/blob/3a60063a54d850c50c50c50ce962a8a39ce01cfee71398/aio/aio/aio/src/src/src/src/app/shard/shared/shared/reporting-erporting-ertring-error handler.spec.ts)依赖性" appModule"

it('should be registered on the AppModule', () => {
   handler = TestBed.configureTestingModule({ imports: [AppModule] }).inject(ErrorHandler) as any;
   expect(handler).toEqual(jasmine.any(BkExceptionHandlerService));
});

您真的不应该测试触发错误时,错误处理程序会捕获它,因为您将测试框架而不是代码。

相关内容

最新更新