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

时间:2018-10-19 11:06:11

标签: unit-testing exception cakephp integration-testing cakephp-3.x

我正在尝试测试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,但是没有运气。是否可以测试异常?

1 个答案:

答案 0 :(得分:1)

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

这是由于您的应用程序使用错误处理程序中间件(请参见src/Application.php)引起的,该中间件将捕获包装的代码中引发的异常并相应地呈现错误页面/响应,或者是由于集成测试用例执行类似的操作,即它将捕获可能的异常(\PHPUnit\Exception\Cake\Database\Exception\DatabaseExceptionLogicException除外)并呈现错误页面/响应,以使异常不会冒泡到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*()方法。