Утверждение исключений в тестах Laravel 11
В недавнем релизе Laravel 11.4 появился фасад Exceptions, добавляющий удобства для утверждения исключений в обработчике исключений Laravel. До этого релиза обычно использовали $this->withoutExceptionHandling()
, чтобы подтвердить, что определённое исключение произошло во время HTTP-теста:
use App\Exceptions\WelcomeException;
$this->withoutExceptionHandling();
try {
$this->get('/');
} catch (WelcomeException $e) {
$this->assertEquals('Woops, there was an issue with your request!', $e->getMessage());
return;
}
$this->fail(sprintf('The expected "%s" exception was not thrown.', WelcomeException::class));
Когда ожидается, что запрос не будет выбрасывать никаких исключений, использование withoutExceptionHandling
избавляет от посредника при отладке того, почему возникает ошибка, когда этого не ожидаешь. Приведённый выше код очень утомителен, потому что он вручную перехватывает исключение, создаёт утверждения об исключении и вызывает return
, чтобы избежать ручного вызова $this->fail()
. Вручную отлавливаются ситуации, когда тест не выбрасывает исключение, когда оно ожидается.
Если в приведённом сценарии вызвать $this->fail()
, то результат будет выглядеть так:
phpunit
There was 1 failure:
1) Tests\Feature\ExampleTest::test_the_application_returns_a_successful_response
The expected "App\Exceptions\WelcomeException" exception was not thrown.
/app/tests/Feature/ExampleTest.php:33
Фасад Exceptions в Laravel 11
Давайте посмотрим, как новый фасад Exceptions
может упростить тест; первый пример, переписанный заново, будет выглядеть так:
use Illuminate\Support\Facades\Exceptions;
Exceptions::fake();
$this->get('/');
Exceptions::assertReported(function (WelcomeException $e): bool {
return $e->getMessage() === "Woops, there was an issue with your request!";
});
Использование фасада Exceptions
даёт бонус в виде отсутствия необходимости перехватывать исключение для утверждения вручную. Другими словами, тест может сохранить обработчик исключений Laravel на месте, но при этом иметь возможность утверждать исключения, произошедшие во время запроса.
Если необходимо убедиться, что тест не выбросит определённое исключение или не выбросит ни одного исключения вообще, новый фасад нас прикроет:
Exceptions::assertNotReported(WelcomeException::class);
Exceptions::assertNothingReported();
Если обработчик исключений не сообщает о WelcomeException
, тестовый вывод выдаст красиво оформленное сообщение:
phpunit
There was 1 failure:
1) Tests\Feature\ExampleTest::test_the_application_returns_a_successful_response
The expected [App\Exceptions\WelcomeException] exception was not reported.
Хотя бывают случаи, когда не хочется имитировать обработчик исключений Laravel, при тестировании граничных ситуаций новый фасад Exceptions
очень полезен и очищает код:
Exceptions::assertReported(WelcomeException::class);
Exceptions::assertReportedCount($count);
Exceptions::assertNotReported(WelcomeException::class);
Exceptions::assertNothingReported();
Exceptions::throwFirstReported();
Более подробную информацию о фасаде Exceptions
можно найти в документации Laravel.
- Laravel фасады vs псевдонимы классов
- Как безопасно использовать Laravel Фасады
- Laravel: Что такое Фасады и как они работают
- Понимание обработки исключений в Laravel
- Обработка исключений в Laravel: советы и рекомендации