我正在尝试测试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's blog的建议添加了expectException
,我认为这是个好主意:
public function testInternalErrorExceptionIsRaised()
{
$this->enableCsrfToken();
$this->enableSecurityToken();
$formPostData = [];
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
$this->expectException(\Cake\Network\Exception\InternalErrorException::class);
$this->post(
[
'controller' => 'XYZ',
'action' => 'getConfirmation'
],
$formPostData
);
$this->assertResponseFailure();
$this->assertResponseCode(500);
}
错误:
1)App \ Test \ TestCase \ Controller \ XYZControllerTest :: testInternalErrorExceptionIsRaised
断言引发类型为“ Cake \ Network \ Exception \ InternalErrorException”的异常失败。
我尝试了各种方法,但是无法测试CakePHP 3异常。我也尝试过expectExceptionCode()
和expectExceptionMessage
,但是没有运气。是否可以测试异常?
答案 0 :(得分:1)
在控制器(集成)测试中,默认情况下,异常不会进入PHPUnits异常处理程序。
这是由于您的应用程序使用错误处理程序中间件(请参见src/Application.php
)引起的,该中间件将捕获包装的代码中引发的异常并相应地呈现错误页面/响应,或者是由于集成测试用例执行类似的操作,即它将捕获可能的异常(\PHPUnit\Exception
,\Cake\Database\Exception\DatabaseException
和LogicException
除外)并呈现错误页面/响应,以使异常不会冒泡到PHPUnits异常处理程序,这可以防止测试执行被暂停,并允许您测试异常对象以及由应用程序生成的输出(例如错误页面)。
长话短说,在控制器测试中,您必须手动测试抛出的异常,以防您的应用程序 不使用错误处理程序中间件,这可以通过测试来完成\Cake\TestSuite\IntegrationTestCase::$_exception
属性,如下所示:
$this->assertEquals(\Cake\Network\Exception\InternalErrorException::class, $this->_exception);
(此外,您还可以像往常一样通过\Cake\TestSuite\IntegrationTestCase::assertResponse*()
方法或\Cake\TestSuite\IntegrationTestCase::$_response
属性来测试响应)
或者如果您的应用程序 确实使用错误处理程序中间件,并且您想测试异常对象而不是生成的错误响应/页面,则必须确保错误处理程序中间件被“排除”,或者异常被重新抛出,例如可以通过\Cake\TestSuite\IntegrationTestCase::disableErrorHandlerMiddleware()
方法来实现,该方法自CakePHP 3.5.0起可用,例如:
$this->disableErrorHandlerMiddleware();
// ...
$this->post(/* ... */); // < exception will be triggered there and halt the test
这样做时,您可以/必须使用PHPUnits异常声明功能,即注释或expectException*()
方法。