Тестирование ошибок и обещаний с помощью jasmine

#javascript #asynchronous #async-await #promise #jasmine

#javascript #асинхронный #асинхронный -ожидание #обещание #jasmine

Вопрос:

Тестирование ошибок и обещаний. У меня ситуация, похожая на приведенную ниже:

 public myUtilityMethod(): Promise<string> {
  // some synchronous stuff
  console.log('bla bla');
  // some asynchronous stuff
  return Promise.resolve('ok');
}
public async doSomething(): Promise<void> {
  let promise;
  try {
    promise = this.myUtilityMethod();
  } catch (e) {
    throw new MyError('I knew it', e, {});
  }
  await Promise.all([promise]);
  return Promise.resolve();
}
 

Я хочу проверить, когда что-то идет не так в синхронной части myUtilityMethod, я выдаю MyError, поэтому я пишу следующий тест

 it('should throw MyError when something goes wrong in the synchronous part of myUtilityMethod', fakeAsync(() => {
  // given
  const error = new Error('something went wrong');
  component.myUtilityMethod = sinon.stub().throws(error);
  // when
 expect(() => {
   component.doSomething();
   flushMicrotasks();
 }).toThrow(jasmine.any(MyError));
}));
 

Тест завершается неудачно, потому что

         Error: Expected function to throw <jasmine.any(MyError)>, but it threw Error: Uncaught (in promise): MyError: {"message":"i knew it","nativeError":{},"context":{}}.
 

Я упускаю что-то очевидное?

Ответ №1:

Я думаю, что ваше утверждение неверно. Вы издеваетесь над этим doSomething , чтобы бросить new Error('something went wrong') , но вы ожидаете MyError .

myUtilityMethod Я бы попытался выбросить so, затем он попадает в ваш блок и должен быть пройден. Error catch throw new MyError('I knew it', e, {})

 it('should throw MyError when something goes wrong in the synchronous part of myUtilityMethod', fakeAsync(() => {
  // given
  const error = new Error('something went wrong');
  component.myUtilityMethod = sinon.stub().throws(error); // make myUtilityMethod throw the error
  // when
 expect(() => {
   component.doSomething(); // once myUtilityMethod throws the error, doSomething's catch block will run
   flushMicrotasks();
 }).toThrow(new LabelGenerationError('I knew it', error, {}));
}));
 

Редактировать: после просмотра вашей новой ошибки:

 // change this line to back to how it was
.toThrow(jasmine.any(MyError));
// to this
.toThrow(new LabelGenerationError('I knew it', error, {}));
 

Комментарии:

1. Вы абсолютно правы, я допустил ошибку при написании вопроса. Тем не менее, он все еще стоит.

2. Проверьте свою ошибку и посмотрите expected vs actual . Посмотрите мою правку. Я думаю, что это все.

3. Я обнаружил, в чем проблема на самом деле. async Функция оборачивает все свое содержимое в обещание. Итак, чтобы проверить то, что я пытаюсь, мне нужно использовать promise.catch.

Ответ №2:

async функции заключают все свое содержимое в обещание, поэтому, даже если ошибка выдается до того, как возникнет какое-либо «ожидание», происходит то, что обещание отклоняется, а не выдает ошибку. Следующий тест проходит:

   it('test test', (done) => {
    const error = new Error('something went wrong');
    component.myUtilityMethod = sinon.stub().throws(error);

    component.doSomething().catch((e) => {
      expect(e).toEqual(jasmine.any(MyError));
      done();
    });
  });