Как проверить ошибку, сгенерированную при подписке - PullRequest
0 голосов
/ 02 ноября 2018

Я тестирую функцию вызова ниже в угловом 4.

import { Component, OnInit } from '@angular/core';
import { AppService } from './app.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  title = 'jasmine-error-test';

  constructor(private appService: AppService) { }

  ngOnInit(): void {
    this.call();
  }

  call() {
    return this.appService.load().subscribe((res) => {
      this.title = res;
    }, (err) => {
      throw new Error('Failed');
    });
  }

}

Чтобы проверить часть, где из-за подписки выдается ошибка, я делаю следующее.

describe('when call is called', () => {
    describe('when the service returns an error', () => {
      let app;
      beforeEach(async(() => {
        const fixture = TestBed.createComponent(AppComponent);
        app = fixture.componentInstance;
        (service.load as jasmine.Spy).and.returnValue(Observable.throw({
          status: 406,
          error: {
            message: 'Test 406 error'
          }
        }));
      }));
      it('it should throw a  matching error', async(() => {
        expect(() => { app.call(); }).toThrowError('Failed');
      }));
    });
  });

Но проверка не проходит с ошибкой

Expected function to throw an Error.

Если я использую окно отладчика, в нем отображается строка, в которую выдается ошибка, но я все равно не могу пройти тест. Может кто-нибудь дать мне знать, что происходит.

1 Ответ

0 голосов
/ 03 ноября 2018

Интересный вопрос. Обработка ошибок с помощью Observables довольно сложна. Как вы узнали, повторное генерирование ошибки нетривиально, потому что способ отловить такую ​​ошибку находится в блоке try / catch, но это не работает с асинхронным кодом. :) В Интернете много хороших обсуждений по этому поводу, вот что я нашел: Обработка ошибок в Реактивных расширениях .

Я бы предложил рефакторинг вашего кода. Если возникает ошибка, вы можете перехватить детали в переменной компонента, как вы это уже делаете с this.title. Возможно, назовите его this.error, тогда вы можете проверить, что он имеет значение null (без ошибок) или имеет значение (в случае ошибки). Возможно рефакторинг такой:

call() {
    return this.appService.load().subscribe((res) => {
        this.title = res;
    }, (err) => {
        this.error = err;
        // throw new Error('Failed');
    });
}

Тогда ваш тест будет выглядеть примерно так:

it('it should capture any error in this.error', () => {
    // expect(() => { app.call(); }).toThrowError('Failed');
    app.call();
    expect(app.error).toEqual(/* testError */);
});

В случае, если это полезно для вас, вот набор стеков, который я собрал, чтобы опробовать некоторые идеи по этому вопросу: Как проверить ошибку, выданную подпиской

...