在 Laravel 测试中断言异常
发布于 作者 Paul Redmond
Laravel 最近发布的 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_responseThe expected "App\Exceptions\WelcomeException" exception was not thrown. /app/tests/Feature/ExampleTest.php:33
Laravel 的异常门面
让我们看看新的 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!";});
使用异常门面,我们不必捕获异常来手动断言。换句话说,测试可以保持 Laravel 的异常处理程序,但仍然能够断言请求期间发生的异常。
如果我们想确保测试不抛出特定异常,或者根本不抛出任何异常,新的门面可以满足我们的需求
Exceptions::assertNotReported(WelcomeException::class); Exceptions::assertNothingReported();
如果异常处理程序没有报告 WelcomeException
,则测试输出将为我们提供一条格式良好的消息
$ phpunit There was 1 failure: 1) Tests\Feature\ExampleTest::test_the_application_returns_a_successful_responseThe expected [App\Exceptions\WelcomeException] exception was not reported.
虽然有时您可能不想模拟 Laravel 的异常处理程序,但在测试边缘情况时,新的异常门面非常有用,可以清理我们的代码
Exceptions::assertReported(WelcomeException::class);Exceptions::assertReportedCount($count);Exceptions::assertNotReported(WelcomeException::class);Exceptions::assertNothingReported();Exceptions::throwFirstReported();
要详细了解异常门面,请查看 Laravel 文档。