#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
vsactual
. Посмотрите мою правку. Я думаю, что это все.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();
});
});