Skip to content

Commit 1301d9c

Browse files
[11.x] Inspect exception of assertThrows (#52224)
* Inspect exception of assertThrows * Update InteractsWithExceptionHandling.php --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 29a58fe commit 1301d9c

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/Illuminate/Foundation/Testing/Concerns/InteractsWithExceptionHandling.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Closure;
66
use Illuminate\Contracts\Debug\ExceptionHandler;
77
use Illuminate\Support\Testing\Fakes\ExceptionHandlerFake;
8+
use Illuminate\Support\Traits\ReflectsClosures;
89
use Illuminate\Testing\Assert;
910
use Illuminate\Validation\ValidationException;
1011
use Symfony\Component\Console\Application as ConsoleApplication;
@@ -13,6 +14,8 @@
1314

1415
trait InteractsWithExceptionHandling
1516
{
17+
use ReflectsClosures;
18+
1619
/**
1720
* The original exception handler.
1821
*
@@ -169,18 +172,22 @@ public function renderForConsole($output, Throwable $e)
169172
* Assert that the given callback throws an exception with the given message when invoked.
170173
*
171174
* @param \Closure $test
172-
* @param class-string<\Throwable> $expectedClass
175+
* @param \Closure|class-string<\Throwable> $expectedClass
173176
* @param string|null $expectedMessage
174177
* @return $this
175178
*/
176-
protected function assertThrows(Closure $test, string $expectedClass = Throwable::class, ?string $expectedMessage = null)
179+
protected function assertThrows(Closure $test, string|Closure $expectedClass = Throwable::class, ?string $expectedMessage = null)
177180
{
181+
[$expectedClass, $expectedClassCallback] = $expectedClass instanceof Closure
182+
? [$this->firstClosureParameterType($expectedClass), $expectedClass]
183+
: [$expectedClass, null];
184+
178185
try {
179186
$test();
180187

181188
$thrown = false;
182189
} catch (Throwable $exception) {
183-
$thrown = $exception instanceof $expectedClass;
190+
$thrown = $exception instanceof $expectedClass && ($expectedClassCallback === null || $expectedClassCallback($exception));
184191

185192
$actualMessage = $exception->getMessage();
186193
}

tests/Foundation/FoundationExceptionsHandlerTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,42 @@ public function testAssertExceptionIsThrown()
533533
if ($testFailed) {
534534
Assert::fail('assertThrows failed: non matching message are thrown.');
535535
}
536+
537+
$this->assertThrows(function () {
538+
throw new CustomException('Some message.');
539+
}, function (CustomException $exception) {
540+
return $exception->getMessage() === 'Some message.';
541+
});
542+
543+
try {
544+
$this->assertThrows(function () {
545+
throw new CustomException('Some message.');
546+
}, function (CustomException $exception) {
547+
return false;
548+
});
549+
$testFailed = true;
550+
} catch (AssertionFailedError) {
551+
$testFailed = false;
552+
}
553+
554+
if ($testFailed) {
555+
Assert::fail('assertThrows failed: exception callback succeeded.');
556+
}
557+
558+
try {
559+
$this->assertThrows(function () {
560+
throw new Exception('Some message.');
561+
}, function (CustomException $exception) {
562+
return true;
563+
});
564+
$testFailed = true;
565+
} catch (AssertionFailedError) {
566+
$testFailed = false;
567+
}
568+
569+
if ($testFailed) {
570+
Assert::fail('assertThrows failed: non matching exceptions are thrown.');
571+
}
536572
}
537573

538574
public function testItReportsDuplicateExceptions()

0 commit comments

Comments
 (0)