使用 CakePHP 的集成测试用例时如何测试异常?



我正在尝试测试我的 CakePHP 3 内部错误异常。

我的控制器:

public function getConfirmation()
{
if (!$this->request->getData())
throw new InternalErrorException(__('data not found'));
$confirmStatus = $this->XYZ->getConfirmation($this->request->getData('ID'), $this->request->getData('MANAGER_ID'));
$this->set([
'confirmStatus' => ($confirmStatus) ? 1 : 0,
]);
}

在异常测试中,我按照Sebastian Bergmann博客上的建议添加了expectException,我认为这是一个好主意:

public function testInternalErrorExceptionIsRaised()
{
$this->enableCsrfToken();
$this->enableSecurityToken();
$formPostData = [];
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$this->expectException(CakeNetworkExceptionInternalErrorException::class);
$this->post(
[
'controller' => 'XYZ',
'action' => 'getConfirmation'
],
$formPostData
);
$this->assertResponseFailure();
$this->assertResponseCode(500);
}

错误:

1( App\Test\TestCase\Controller\XYZControllerTest::testInternalErrorExceptionIsRaise

断言引发类型为"Cake\Network\Exception\InternalErrorException"的异常失败。

我已经尝试了各种方法,但无法测试 CakePHP 3 异常。我也尝试过expectExceptionCode()expectExceptionMessage,但没有运气。是否可以测试异常?

在控制器(集成(测试中,默认情况下异常不会进入 PHPUnits 异常处理程序。

这是由使用错误处理程序中间件的应用程序引起的(请参阅src/Application.php(,它将捕获它包装的代码中抛出的异常,并相应地呈现错误页面/响应,或者因为集成测试用例执行类似的事情,也就是说,它将捕获可能的异常(PHPUnitExceptionCakeDatabaseExceptionDatabaseExceptionLogicException除外(并呈现错误页面/响应, 这样异常就不会冒泡到 PHPUnits 异常处理程序,这可以防止测试执行停止,并允许您测试异常对象以及应用程序生成的输出(例如错误页(。

长话短说,在控制器测试中,您必须手动测试引发的异常,以防应用程序不使用错误处理程序中间件,这可以通过测试CakeTestSuiteIntegrationTestCase::$_exception属性来完成,如下所示:

$this->assertEquals(CakeNetworkExceptionInternalErrorException::class, $this->_exception);

(此外,您可以像往常一样通过例如CakeTestSuiteIntegrationTestCase::assertResponse*()方法或CakeTestSuiteIntegrationTestCase::$_response属性测试响应(

或者,如果您的应用程序确实使用了错误处理程序中间件,并且您想要测试异常对象而不是生成的错误响应/页面,则必须确保错误处理程序中间件被"排除",分别是重新抛出异常,例如,这可以通过CakeTestSuiteIntegrationTestCase::disableErrorHandlerMiddleware()方法实现,该方法从 CakePHP 3.5.0 开始可用, 喜欢这个:

$this->disableErrorHandlerMiddleware();
// ...
$this->post(/* ... */); // < exception will be triggered there and halt the test

这样做时,您可以/必须使用 PHPUnits 异常断言功能,即注释或expectException*()方法。

最新更新