phpUnit - фиктивный объект расширенного исключения php - PullRequest
2 голосов
/ 14 мая 2010

Я тестирую некоторый устаревший код, который расширяет объект исключения php по умолчанию. Этот код выводит пользовательское сообщение об ошибке HTML.

Я хотел бы смоделировать этот объект исключения таким образом, чтобы, когда тестируемый код генерировал исключение, он просто отображал основное сообщение вместо того, чтобы давать мне полное сообщение HTML.

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

Полагаю, проблема в том, куда бы вы прикрепили высмеиваемый объект? Кажется, что вы не можете вмешиваться в «throw new», и это то место, где вызывается метод объекта ....

Или, если бы вы могли каким-то образом использовать существующую функциональность исключений phpunit, чтобы изменить поведение исключений так, как вы хотите, в общем случае для всего вашего кода ... но кажется, что это будет хакерским и плохим ....

РЕДАКТИРОВАТЬ: вот код, чтобы прояснить ситуацию:

class FooTest extends PHPUnit_Framework_TestCase{

    public function testBar(){
        include '/path/to/file.php'; //generates exception

        $this->assertTrue($baz);             
    }
}
 ...
//overridden exception class
class Foo_Exception extends ErrorException{
 ...

Итак, мой вопрос, есть ли способ справиться с этим переопределенным классом, не делая это в каждом конкретном случае? Что делать, если я не тестирую поведение исключения, просто код, который вызывает исключение?

Ответы [ 3 ]

1 голос
/ 15 мая 2010

Я бы сначала написал тест, который фиксирует поведение генерации исключения:

include '/path/to/file.php'; //generates exception
public function testCatchFooException() {
    try {
        $this->assertTrue($baz);             
    }
    catch (Exception $expected) {
        $this->assertEquals('This is expected html from exception', $expected->getMessage());
        return;
    }

    $this->fail('An expected Exception has not been raised Foo_Excpetion.');
}

Теперь вы можете сделать несколько вещей с этим тестом покрытия. Вы можете исправить исключение или исправить код, который вызывает исключение.

Еще одна вещь, которую вы можете сделать - это обернуть весь file.php в класс:

 class FooClass {

    function runFoo() {
        include '/path/to/file.php'; //generates exception

    }   

}

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

[EDIT]

Вот несколько серьезных процедурных устаревших кодов:

<?php
require_once 'helper.php';  //helper file

function countNewMessages($user_id) {
}

function countNewOrders() {
}

function countNewReturns() {
}

function getDB($init = NULL) {
}

function getDisplay() {
}

getDisplay();

?>

А вот и завернутый класс:

<?php
require_once '';  //helper file

class Displayer {
    function countNewMessages($user_id) {
    }

    function countNewOrders() {
    }

    function countNewReturns() {
    }

    function getDB($init = NULL) {
    }

    function getDisplay() {
    }
}
?>

А теперь я могу это проверить:

    function testGetDisplay() {
    $display = new Displayer();

    $this->assertEquals('html code', $display->getDisplay());
}

И проверить отдельные функции в нем. И если я могу дальше прорасти методы на этом.

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

0 голосов
/ 14 мая 2010

ОК, я неправильно понял вопрос. Если тестируемый сценарий улавливает ошибку и затем отображает страницу с ошибкой, то это не имеет ничего общего с исключениями. Вы можете использовать семейство ob_:

ob_start();
include $file;
$contents = ob_get_contents();

if (result_is_error($contents))
    die(extract_error_from_result($contents));
else
    echo $contents;

ob_end_clean();
0 голосов
/ 14 мая 2010

Расширенный объект исключения PHP "печатает" страницу ошибки HTML-кода?Вы имеете в виду, что сообщение об ошибке - это целая страница HTML?Это не очень умно ...

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

set_exception_handler(
    function (Exception $e) {
        die(parse_html_error_page($e->getMessage()));
    }
);
...