Angular / RxJS 6 - Как выполнить модульное тестирование инструкций, вызванных функцией next (), сгенерировать исключение - PullRequest
0 голосов
/ 14 мая 2018

Перед миграцией на RxJs6 один из моих модульных тестов был:

it('should do what I expect, () => {
  expect(() => {
    myComponent.mySubject.next({message: 'invalid'});
  }).toThrow('invalid is not an accepted message');
})

В моем компоненте я подписываюсь на тему и вызываю закрытый метод, который может вызвать исключение.Что-то похожее на это:

export class MyComponent {
  //...
  mySubject = new Subject();
  //...
  ngOnInit(){
    this.mySubject.subscribe(obj => this._doSomething(obj))
  }
  //...
  private _doSomething(obj) {
    if ('invalid' === obj.message) {
      throw new Error('invalid is not an accepted message');
    }
    //...
  }
}

Поскольку я перешел на RxJs6, этот UT больше не работает (он работал раньше), и я не могу понять, как заставить его работать.

Я прочиталРуководство по миграции, особенно этот раздел: Замена синхронной обработки ошибок , но речь идет о subscribe(), а не next() ...

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Я нашел обходной путь.

Не уверен насчет актуальности, но мне кажется, это работает.

Я использую методы углового тестирования fakeAsync и tick, чтобы инициировать выброс необработанного исключения.

Преобразование:

it('should do what I expect, () => {
  expect(() => {
    myComponent.mySubject.next({message: 'invalid'});
  }).toThrow('invalid is not an accepted message');
})

в:

it('should do what I expect, fakeAsync(() => {
  myComponent.mySubject.next({message: 'invalid'});
  expect(() => tick())
    .toThrow('invalid is not an accepted message');
}))

Кстати, этот трюк также позволяет мне быть уверенным, что, если исключение не будет сгенерировано, тест не пройдёт.

0 голосов
/ 14 мая 2018

Это верно. В RxJS 5 при подписке с subscribe, если вы не установили обработчик error, ошибка была просто повторно выдана. Вот почему ваш модульный тест работал раньше.

Но это не так, как в RxJS 6, потому что все необработанные ошибки перебрасываются в window.onerror или process.on('error') (в зависимости от вашей среды).

Что вы можете сделать, это сделать тестовую асинхронность и затем проверить, что один из описанных выше обработчиков был назван:

it('should do what I expect, done => {
  process.once('error', () => done());

  myComponent.mySubject.next({message: 'invalid'});
});

Это стиль mocha, но я думаю, что в Жасмин это будет похоже.

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

Мне потребовалось некоторое время, чтобы найти соответствующий коммит, но прочитайте описание здесь https://github.com/ReactiveX/rxjs/commit/cd9626a4f93cac6f631d5a97dd9c9b2aa8e4b5db (упомянуто также в CHANGELOG.md).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...