From f8930d20aed4b598426e4ffa8b7910428484dbe9 Mon Sep 17 00:00:00 2001 From: Fabio Ivona Date: Mon, 1 May 2023 21:42:47 +0200 Subject: [PATCH] allows to check toThrow against an exception instance --- src/Mixins/Expectation.php | 13 +++++++++++-- tests/Features/Expect/toThrow.php | 13 +++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 3bfcdadd..25043a48 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -842,7 +842,7 @@ final class Expectation * @param (Closure(Throwable): mixed)|string $exception * @return self */ - public function toThrow(callable|string $exception, string $exceptionMessage = null, string $message = ''): self + public function toThrow(callable|string|Throwable $exception, string $exceptionMessage = null, string $message = ''): self { $callback = NullClosure::create(); @@ -864,6 +864,15 @@ final class Expectation try { ($this->value)(); } catch (Throwable $e) { + + if ($exception instanceof Throwable) { + expect($e) + ->toBeInstanceOf($exception::class, $message) + ->and($e->getMessage())->toBe($exceptionMessage ?? $exception->getMessage(), $message); + + return $this; + } + if (! class_exists($exception)) { if ($e instanceof Error && $e->getMessage() === "Class \"$exception\" not found") { Assert::assertTrue(true); @@ -888,7 +897,7 @@ final class Expectation Assert::assertTrue(true); - if (! class_exists($exception)) { + if (! $exception instanceof Throwable && ! class_exists($exception)) { throw new ExpectationFailedException("Exception with message \"$exception\" not thrown."); } diff --git a/tests/Features/Expect/toThrow.php b/tests/Features/Expect/toThrow.php index e3cd0133..67750c0b 100644 --- a/tests/Features/Expect/toThrow.php +++ b/tests/Features/Expect/toThrow.php @@ -2,6 +2,10 @@ use PHPUnit\Framework\ExpectationFailedException; +class CustomException extends Exception +{ +} + test('passes', function () { expect(function () { throw new RuntimeException(); @@ -33,6 +37,9 @@ test('passes', function () { throw new RuntimeException('actual message'); })->toThrow(function (RuntimeException $e) { }, 'actual message'); + expect(function () { + throw new CustomException('foo'); + })->toThrow(new CustomException('foo')); }); test('failures 1', function () { @@ -79,6 +86,12 @@ test('failures 7', function () { })->toThrow(RuntimeException::class, 'expected message'); })->throws(ExpectationFailedException::class); +test('failures 8', function () { + expect(function () { + throw new CustomException('actual message'); + })->toThrow(new CustomException('expected message')); +})->throws(ExpectationFailedException::class); + test('failures with custom message', function () { expect(function () { throw new RuntimeException('actual message');