try..catch
может быть необходимо, если функция способна восстановиться после ошибки, выполнить побочный эффект, например, вести журнал, или повторно выдать более значимую ошибку.
Если CustomError
предпочтительнее, чем ошибка, которую может выдать apiCall
, тогда try..catch
необходимо, иначе - нет. Также проблема с foo
заключается в том, что он обрабатывает только синхронные ошибки. Чтобы обработать отклоненные обещания, оно должно быть return await apiCall()
, это известная ловушка async
.
Неперехваченные отклонения нежелательны, в настоящее время они приводят к UnhandledPromiseRejectionWarning
и, как ожидается, сработают sh Node в будущих версиях. Предпочтительно обрабатывать ошибку осмысленным образом на верхнем уровне, поэтому main
необходимо перехватить ошибку. Это можно делегировать обработчику событий process
uncaughtRejection
, но для него может быть полезно сохранить дополнительный уровень обработки ошибок, который никогда не должен быть достигнут.
В результате мы видим, что Unhandled Отклонение обещания регистрируется в консоли.
Этого не должно происходить. Отклонение должно быть обработано тестом. Одна из возможных точек отказа объяснена выше: foo
может возвращать исходную ошибку из apiCall
вместо CustomError
в случае, если он был неправильно смоделирован, это не соответствует ожиданиям и приведет к необработанному отклонению в catch()
. Другой момент отказа заключается в том, что у теста есть несвязанное обещание, потому что оно не было возвращено, тест всегда проходит.
Асинхронный тест, который использует обещания, всегда должен возвращать обещание. Это можно улучшить, используя async..await
. foo
равно async
, ожидается, что он всегда будет возвращать обещание:
it('foo should throw', async () => {
foo.mockImplementantion(() => { return Promise.reject(new CustomError('error')) });
await expect(bar()).rejects.toThrow(CustomError);
})
Теперь, даже если foo
mock терпит неудачу (foo
mock не повлияет на bar
, если они определены в тот же модуль, как показано) и bar
отклоняет с чем-то, что не CustomError
, это будет подтверждено.