Как поймать ошибку неопределенного индекса E_NOTICE в simpleTest?

Я хотел бы написать тест с использованием simpleTest, который потерпит неудачу, если метод, который я тестирую, приведет к PHP E_NOTICE «undefined index: foo».

Я пробовал expectError() и expectException() безуспешно. На веб-странице simpleTest указано, что simpleTest не может обнаруживать ошибки PHP времени компиляции, но E_NOTICE кажется ошибкой времени выполнения.

Есть ли способ поймать такую ​​​​ошибку и сделать мой тест неудачным, если это так?


person pixelastic    schedule 16.07.2010    source источник


Ответы (4)


Это было не очень просто, но мне наконец удалось поймать ошибку E_NOTICE, которую я хотел. Мне нужно было переопределить текущий error_handler, чтобы создать исключение, которое я поймаю в выражении try{}.

function testGotUndefinedIndex() {
    // Overriding the error handler
    function errorHandlerCatchUndefinedIndex($errno, $errstr, $errfile, $errline ) {
        // We are only interested in one kind of error
        if ($errstr=='Undefined index: bar') {
            //We throw an exception that will be catched in the test
            throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
        }
        return false;
    }
    set_error_handler("errorHandlerCatchUndefinedIndex");

    try {
        // triggering the error
        $foo = array();
        echo $foo['bar'];
    } catch (ErrorException $e) {
        // Very important : restoring the previous error handler
        restore_error_handler();
        // Manually asserting that the test fails
        $this->fail();
        return;
    }

    // Very important : restoring the previous error handler
    restore_error_handler();
    // Manually asserting that the test succeed
    $this->pass();
}

Это кажется слишком сложным, чтобы повторно объявить обработчик ошибок, чтобы генерировать исключение только для того, чтобы его перехватить. Другая трудная часть заключалась в правильном восстановлении error_handler как при перехвате исключения, так и при отсутствии ошибки, в противном случае это просто портит обработку ошибок SimpleTest.

person pixelastic    schedule 16.07.2010
comment
Какой это ужасный язык! - person m93a; 13.03.2015
comment
Если вы укажете E_NOTICE в качестве второго параметра для set_error_handler, он будет обрабатывать только уведомления. Может использоваться для маскировки срабатывания функции error_handler, точно так же, как ini-настройка error_reporting определяет отображаемые ошибки. Без этой установленной маски error_handler будет вызываться для каждой ошибки независимо от настройки параметра error_reporting. - person nick; 24.01.2018

На самом деле нет необходимости ловить ошибку уведомления. Можно также проверить результат «array_key_exists», а затем продолжить оттуда.

http://www.php.net/manual/en/function.array-key-exists.php

Тест на ложь и провал.

person Robert Brisita    schedule 19.04.2013
comment
Если голосование против, пожалуйста, объясните, почему. - person Robert Brisita; 10.03.2017
comment
Есть случай, когда вы проецируете массив в другой массив. Вы не хотите тестировать каждую отдельную карту, вы хотите поймать случай, когда какое-либо из сопоставлений не работает. Это было бы намного проще с исключениями. - person CMCDragonkai; 15.03.2017

Вы никогда не поймаете его в блоке try-catch, к счастью, у нас есть set_error_handler():

<?php
function my_handle(){}
set_error_handler("my_handle");
echo $foo["bar"];
?>

Вы можете делать все, что хотите внутри функции my_handle(), или просто оставить ее пустой, чтобы отключить уведомление, хотя это не рекомендуется. Нормальный обработчик должен быть таким:

function myErrorHandler($errno, $errstr, $errfile, $errline)
person John Lee    schedule 23.09.2017
comment
Лучший ответ, который на самом деле прост и работает, не знаю, почему у него нет голосов ... но мой № 3 - person kungfooman; 05.02.2020

Многие решения для обработки ошибок E_NOTICE at sign игнорируют все ошибки E_NOTICE. Чтобы игнорировать только ошибки из-за использования знаков at, сделайте это в своей функции обратного вызова set_error_handler:

if (error_reporting()==0 && $errno==E_NOTICE)
    return; // Ignore notices for at sign

Вот пример важного сообщения E_NOTICE, которое нельзя игнорировать:

$a=$b;

потому что $b не определено.

person David Spector    schedule 24.06.2021