diff --git a/src/Illuminate/Foundation/Testing/TestCase.php b/src/Illuminate/Foundation/Testing/TestCase.php index b546ad63591e..a782aeb79f9a 100644 --- a/src/Illuminate/Foundation/Testing/TestCase.php +++ b/src/Illuminate/Foundation/Testing/TestCase.php @@ -6,21 +6,16 @@ use Illuminate\Console\Application as Artisan; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Bootstrap\HandleExceptions; -use Illuminate\Http\RedirectResponse; use Illuminate\Queue\Queue; -use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Facade; use Illuminate\Support\Facades\ParallelTesting; use Illuminate\Support\Str; -use Illuminate\Testing\AssertableJsonString; use Illuminate\View\Component; use Mockery; use Mockery\Exception\InvalidCountException; -use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\TestCase as BaseTestCase; use PHPUnit\Util\Annotation\Registry; -use ReflectionProperty; use Throwable; abstract class TestCase extends BaseTestCase @@ -301,111 +296,10 @@ protected function callBeforeApplicationDestroyedCallbacks() */ protected function onNotSuccessfulTest(Throwable $exception): void { - if (! $exception instanceof ExpectationFailedException || is_null(static::$latestResponse)) { - parent::onNotSuccessfulTest($exception); - } - - if ($lastException = static::$latestResponse->exceptions->last()) { - parent::onNotSuccessfulTest($this->appendExceptionToException($lastException, $exception)); - - return; - } - - if (static::$latestResponse->baseResponse instanceof RedirectResponse) { - $session = static::$latestResponse->baseResponse->getSession(); - - if (! is_null($session) && $session->has('errors')) { - parent::onNotSuccessfulTest($this->appendErrorsToException($session->get('errors')->all(), $exception)); - - return; - } - } - - if (static::$latestResponse->baseResponse->headers->get('Content-Type') === 'application/json') { - $testJson = new AssertableJsonString(static::$latestResponse->getContent()); - - if (isset($testJson['errors'])) { - parent::onNotSuccessfulTest($this->appendErrorsToException($testJson->json(), $exception, true)); - - return; - } - } - - parent::onNotSuccessfulTest($exception); - } - - /** - * Append an exception to the message of another exception. - * - * @param \Throwable $exceptionToAppend - * @param \Throwable $exception - * @return \Throwable - */ - protected function appendExceptionToException($exceptionToAppend, $exception) - { - $exceptionMessage = $exceptionToAppend->getMessage(); - - $exceptionToAppend = (string) $exceptionToAppend; - - $message = <<<"EOF" - The following exception occurred during the last request: - - $exceptionToAppend - - ---------------------------------------------------------------------------------- - - $exceptionMessage - EOF; - - return $this->appendMessageToException($message, $exception); - } - - /** - * Append errors to an exception message. - * - * @param array $errors - * @param \Throwable $exception - * @param bool $json - * @return \Throwable - */ - protected function appendErrorsToException($errors, $exception, $json = false) - { - $errors = $json - ? json_encode($errors, JSON_PRETTY_PRINT) - : implode(PHP_EOL, Arr::flatten($errors)); - - // JSON error messages may already contain the errors, so we shouldn't duplicate them... - if (str_contains($exception->getMessage(), $errors)) { - return $exception; - } - - $message = <<<"EOF" - The following errors occurred during the last request: - - $errors - EOF; - - return $this->appendMessageToException($message, $exception); - } - - /** - * Append a message to an exception. - * - * @param string $message - * @param \Throwable $exception - * @return \Throwable - */ - protected function appendMessageToException($message, $exception) - { - $property = new ReflectionProperty($exception, 'message'); - - $property->setAccessible(true); - - $property->setValue( - $exception, - $exception->getMessage().PHP_EOL.PHP_EOL.$message.PHP_EOL + parent::onNotSuccessfulTest( + is_null(static::$latestResponse) + ? $exception + : static::$latestResponse->transformNotSuccessfulException($exception) ); - - return $exception; } } diff --git a/src/Illuminate/Testing/TestResponse.php b/src/Illuminate/Testing/TestResponse.php index a9fb16968712..e562797f4298 100644 --- a/src/Illuminate/Testing/TestResponse.php +++ b/src/Illuminate/Testing/TestResponse.php @@ -9,6 +9,7 @@ use Illuminate\Cookie\CookieValuePrefix; use Illuminate\Database\Eloquent\Collection as EloquentCollection; use Illuminate\Database\Eloquent\Model; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Arr; use Illuminate\Support\Carbon; @@ -21,6 +22,8 @@ use Illuminate\Testing\Constraints\SeeInOrder; use Illuminate\Testing\Fluent\AssertableJson; use LogicException; +use PHPUnit\Framework\ExpectationFailedException; +use ReflectionProperty; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\StreamedResponse; @@ -1549,6 +1552,116 @@ public function withExceptions(Collection $exceptions) return $this; } + /** + * This method is called when test method did not execute successfully. + * + * @param \Throwable $exception + * @return \Throwable + */ + public function transformNotSuccessfulException($exception) + { + if (! $exception instanceof ExpectationFailedException) { + return $exception; + } + + if ($lastException = $this->exceptions->last()) { + return $this->appendExceptionToException($lastException, $exception); + } + + if ($this->baseResponse instanceof RedirectResponse) { + $session = $this->baseResponse->getSession(); + + if (! is_null($session) && $session->has('errors')) { + return $this->appendErrorsToException($session->get('errors')->all(), $exception); + } + } + + if ($this->baseResponse->headers->get('Content-Type') === 'application/json') { + $testJson = new AssertableJsonString($this->getContent()); + + if (isset($testJson['errors'])) { + return $this->appendErrorsToException($testJson->json(), $exception, true); + } + } + + return $exception; + } + + /** + * Append an exception to the message of another exception. + * + * @param \Throwable $exceptionToAppend + * @param \Throwable $exception + * @return \Throwable + */ + protected function appendExceptionToException($exceptionToAppend, $exception) + { + $exceptionMessage = $exceptionToAppend->getMessage(); + + $exceptionToAppend = (string) $exceptionToAppend; + + $message = <<<"EOF" + The following exception occurred during the last request: + + $exceptionToAppend + + ---------------------------------------------------------------------------------- + + $exceptionMessage + EOF; + + return $this->appendMessageToException($message, $exception); + } + + /** + * Append errors to an exception message. + * + * @param array $errors + * @param \Throwable $exception + * @param bool $json + * @return \Throwable + */ + protected function appendErrorsToException($errors, $exception, $json = false) + { + $errors = $json + ? json_encode($errors, JSON_PRETTY_PRINT) + : implode(PHP_EOL, Arr::flatten($errors)); + + // JSON error messages may already contain the errors, so we shouldn't duplicate them... + if (str_contains($exception->getMessage(), $errors)) { + return $exception; + } + + $message = <<<"EOF" + The following errors occurred during the last request: + + $errors + EOF; + + return $this->appendMessageToException($message, $exception); + } + + /** + * Append a message to an exception. + * + * @param string $message + * @param \Throwable $exception + * @return \Throwable + */ + protected function appendMessageToException($message, $exception) + { + $property = new ReflectionProperty($exception, 'message'); + + $property->setAccessible(true); + + $property->setValue( + $exception, + $exception->getMessage().PHP_EOL.PHP_EOL.$message.PHP_EOL + ); + + return $exception; + } + /** * Dynamically access base response parameters. *