InteractsWithExceptionHandling.php
TLDR
This file is a part of the Illuminate/Foundation/Testing/Concerns namespace in the Demo Projects project. It contains a trait called InteractsWithExceptionHandling
which provides methods for handling exceptions in tests.
Methods
withExceptionHandling
Restores exception handling.
handleExceptions
Only handle the given exceptions via the exception handler.
handleValidationExceptions
Only handle validation exceptions via the exception handler.
withoutExceptionHandling
Disables exception handling for the test.
assertThrows
Asserts that the given callback throws an exception with the given message when invoked.
Classes
There are no classes in this file.
<?php
namespace Illuminate\Foundation\Testing\Concerns;
use Closure;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Testing\Assert;
use Illuminate\Validation\ValidationException;
use Symfony\Component\Console\Application as ConsoleApplication;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
trait InteractsWithExceptionHandling
{
/**
* The original exception handler.
*
* @var \Illuminate\Contracts\Debug\ExceptionHandler|null
*/
protected $originalExceptionHandler;
/**
* Restore exception handling.
*
* @return $this
*/
protected function withExceptionHandling()
{
if ($this->originalExceptionHandler) {
$this->app->instance(ExceptionHandler::class, $this->originalExceptionHandler);
}
return $this;
}
/**
* Only handle the given exceptions via the exception handler.
*
* @param array $exceptions
* @return $this
*/
protected function handleExceptions(array $exceptions)
{
return $this->withoutExceptionHandling($exceptions);
}
/**
* Only handle validation exceptions via the exception handler.
*
* @return $this
*/
protected function handleValidationExceptions()
{
return $this->handleExceptions([ValidationException::class]);
}
/**
* Disable exception handling for the test.
*
* @param array $except
* @return $this
*/
protected function withoutExceptionHandling(array $except = [])
{
if ($this->originalExceptionHandler == null) {
$this->originalExceptionHandler = app(ExceptionHandler::class);
}
$this->app->instance(ExceptionHandler::class, new class($this->originalExceptionHandler, $except) implements ExceptionHandler
{
protected $except;
protected $originalHandler;
/**
* Create a new class instance.
*
* @param \Illuminate\Contracts\Debug\ExceptionHandler $originalHandler
* @param array $except
* @return void
*/
public function __construct($originalHandler, $except = [])
{
$this->except = $except;
$this->originalHandler = $originalHandler;
}
/**
* Report or log an exception.
*
* @param \Throwable $e
* @return void
*
* @throws \Exception
*/
public function report(Throwable $e)
{
//
}
/**
* Determine if the exception should be reported.
*
* @param \Throwable $e
* @return bool
*/
public function shouldReport(Throwable $e)
{
return false;
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $e
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Throwable
*/
public function render($request, Throwable $e)
{
foreach ($this->except as $class) {
if ($e instanceof $class) {
return $this->originalHandler->render($request, $e);
}
}
if ($e instanceof NotFoundHttpException) {
throw new NotFoundHttpException(
"{$request->method()} {$request->url()}", $e, is_int($e->getCode()) ? $e->getCode() : 0
);
}
throw $e;
}
/**
* Render an exception to the console.
*
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param \Throwable $e
* @return void
*/
public function renderForConsole($output, Throwable $e)
{
(new ConsoleApplication)->renderThrowable($e, $output);
}
});
return $this;
}
/**
* Assert that the given callback throws an exception with the given message when invoked.
*
* @param \Closure $test
* @param class-string<\Throwable> $expectedClass
* @param string|null $expectedMessage
* @return $this
*/
protected function assertThrows(Closure $test, string $expectedClass = Throwable::class, ?string $expectedMessage = null)
{
try {
$test();
$thrown = false;
} catch (Throwable $exception) {
$thrown = $exception instanceof $expectedClass;
$actualMessage = $exception->getMessage();
}
Assert::assertTrue(
$thrown,
sprintf('Failed asserting that exception of type "%s" was thrown.', $expectedClass)
);
if (isset($expectedMessage)) {
if (! isset($actualMessage)) {
Assert::fail(
sprintf(
'Failed asserting that exception of type "%s" with message "%s" was thrown.',
$expectedClass,
$expectedMessage
)
);
} else {
Assert::assertStringContainsString($expectedMessage, $actualMessage);
}
}
return $this;
}
}