如何测试Angular 2 ErrorHandler实现? [英] How can I test an Angular 2 ErrorHandler implementation?

查看:51
本文介绍了如何测试Angular 2 ErrorHandler实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经重写了@ angular/core ErrorHandler,并且正在尝试对其进行测试,但是却遇到了错误.该服务正常运行,但测试在某处失败.

I have overridden the @angular/core ErrorHandler and I am trying to test it, however I am getting an error. The service works properly but the test fails somewhere.

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并与您走同一条路的类的需求(但在我的情况下,这是一个模拟服务,引发错误),并遇到了测试异常(迫使测试失败)的相同问题.这是一个教科书示例,需要重构以使其更具可测试性.

I've come across the need to test a class that implements ErrorHandler as well and went down the same path as you (but in my case a mock service that raised an error) and ran into the same problem of test exception forcing the test to fail. This is a text book example of needing to refactor to make something more testable.

这也让我感到震惊,我不是仅仅测试我的 handleError()的实现,而且还测试了angular2的ErrorHandler功能.换句话说,该测试的集成度很高,我只需要测试我的 ErrorHandlerService 服务,使其与angular2的错误功能隔离即可.

It also hit me I wasn't JUST testing my implementation of handleError() but also angular2's ErrorHandler functionality. In other words the level of integration for the test was to high, I just needed to test my ErrorHandlerService service in isolation from angular2's error functionality.

这就是我所做的

@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团队已经为您确认了这一点.

You don't need to actually throw new Error(), The Angular2 team has already confirmed that for you.

这篇关于如何测试Angular 2 ErrorHandler实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆