PHPunit - тестирование пользовательского класса обработки ошибок - PullRequest
2 голосов
/ 19 мая 2011

Я хочу протестировать собственный класс обработки ошибок, который я собрал, но это само по себе создает некоторые проблемы.

Прежде всего, поскольку установка собственного обработчика ошибок в тесте переопределяет PHPUnits error_handling, необходимо вызывать restore_error_handler () каждый раз, когда он изменяется на пользовательскую реализацию и тестируется, чтобы в любых последующих тестах phpunits error_handling. Хотя я признаю, что не пробовал, может быть, PHPUnit сбрасывает сам себя после каждого теста, но я в этом немного сомневаюсь.

У меня есть различные конфигурации для тестирования в разных условиях, например, E_ERROR, E_WARNING и т. Д.

У меня тогда возникла идея издеваться над обработчиком ошибок, но я по-прежнему хорошо разбираюсь в насмешливых аспектах тестирования. Быстрый поиск в Google заставил меня найти похожий подход, вот идея, измененная и реализованная таким образом, что может удовлетворить мои потребности ...

//Create mock with error_handler method
$errorH = $this->getMock ('ErrorHandler', array ('error_handler'));

// error handler should be called at least once
$errorH->expects ($this->atLeastOnce())->method ('error_handler');

// Mock will  need to be configured (here?) and tested 
// against specific error_handling settings 
//  not implemented yet nor needed for this post.

//set mock as error handler for duration of this test
set_error_handler (array($errorH, 'error_handler'));

//test current mock error handler configuration 
// for different conditions-> NOTICE / WARNING / ERROR

// Give phpunit's toy back!
restore_error_handler ();

Это правильный подход?

1 Ответ

8 голосов
/ 19 мая 2011

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

Например, допустим, ваш обработчик ошибок выглядел примерно так:

class ErrorHandler
{
    private $logger;

    private $mode;

    public function __construct($mode, $logger) {
        $this->mode = $mode;
        $this->logger = $logger;
    }

    public function handleError($code, $message, $file='', $line=0, $context=array()) {
        if ($code = E_WARNING && $this->mode == 'dev') {
            // warnings are logged in development mode
            $this->logger->log($message, Logger::WARN);
        }
        ...
    }
}

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

function testWarningsAreLoggedInDevelopment() {
    $logger = $this->getMock('Logger', array('log'));
    $logger->expects($this->once())
           ->method('log')
           ->with('message', Logger::WARN);
    $handler = new ErrorHandler('dev', $logger);
    $handler->handleError(E_WARNING, 'message');
}

Прелесть в том, что если ваш обработчик ошибок вызывает ошибку PHP из-за ошибки, PHPUnit перехватит ее и провалит тест. Если вы замените обработчик PHPUnit своим собственным, вы, вероятно, войдете в бесконечный цикл, поскольку PHP снова и снова вызывает ваш обработчик, пока интерпретатор не умрет из-за переполнения стека или из-за нехватки памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...