Как проверить исключения при использовании интеграционного теста CakePHP? - PullRequest
0 голосов
/ 19 октября 2018

Я пытаюсь проверить исключение внутренней ошибки 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,
    ]);
}

В тесте исключений я добавил 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 голосов
/ 19 октября 2018

В тестах контроллера (интеграции) исключения по умолчанию не попадают в обработчик исключений PHPUnits.

Это вызвано тем, что ваше приложение использует промежуточное ПО обработчика ошибок (см. src/Application.php), которое будетпоймать исключение, выброшенное в коде, который он переносит, и соответствующим образом отображает страницу / ответ об ошибке или из-за того, что тестовый пример интеграции делает нечто подобное, то есть он будет перехватывать возможные исключения (за исключением \PHPUnit\Exception, \Cake\Database\Exception\DatabaseException иLogicException) и отображает страницу с ошибкой / ответ, чтобы исключения не всплывали в обработчике исключений PHPUnits, это предотвращает остановку выполнения теста и позволяет протестировать как объект исключения, так и вывод(например, страница ошибки), сгенерированная вашим приложением.

Короче говоря, в тестах контроллера вы должны вручную проверять наличие исключений в случае, если ваше приложение не используетпромежуточное программное обеспечение обработчика ошибок , которое можно сделать, протестировав \Cake\TestSuite\IntegrationTestCase::$_exception propвот так:

$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*().

...