Должен ли я создать пользовательский тип исключения, чтобы мой код был проще для модульного тестирования - PullRequest
0 голосов
/ 01 февраля 2012

В моем модульном тесте я тестирую метод для ожидаемой исключительной ситуации RuntimeException и хочу отличить те, которые были сгенерированы моим компонентом, от тех, которые сгенерированы кодом, вызванным в методе.

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

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

Какова лучшая практика для создания системы кодов ошибок, чтобы они не конфликтовали с внешними пакетами, например. сторонние библиотеки?

Ответы [ 3 ]

1 голос
/ 01 февраля 2012

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

Почему вы считаете, что это не нужно?Это то, что вы должны сделать.Получите ваши собственные классы исключений, выбросьте их экземпляры из вашего кода и поймайте их снаружи (в ваших модульных тестах).Оператор catch может повторяться в ожидании нескольких различных классов исключений:

try {
    // something
} catch (MySpecificException e) {
    // you know that your code threw this
} catch (Exception e) {
    // this is coming from somewhere else
}
0 голосов
/ 01 февраля 2012

Я проверяю метод на ожидаемое исключение RuntimeException

Я думаю, что это ошибка. RuntimeException следует использовать только для указания на ошибки в коде, которые может обнаружить сам код. Тестирование должно проверять только определенное поведение. Но когда в каком-то коде есть ошибка, ее поведение не определено (кто знает, где может быть ошибка или что она может делать). Так что нет смысла пытаться указать, что RuntimeException s должен выдавать какой-то код; это похоже на указание того, как код должен вести себя «при наличии ошибки». Бросать определенные RuntimeException с определенными сообщениями следует рассматривать как любезность программиста обслуживания (который, вероятно, будет вами).

0 голосов
/ 01 февраля 2012

- Edit -

Извините, я не видел тег java. Несмотря на то, что в следующем примере используются конструкции PHP, принципы должны применяться.

- Original -

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

Рассмотрим:

class CoreLib_Api_Exception extends Exception
{
    const EXCEPTION_FORMAT = '%s (%s): %s';

    const CODE_FILE_DNE                 = 100;
    const CODE_DIR_BASE_EQUALS_REMOVE   = 101;

    const CODE_XML_READER_UNABLE_TO_OPEN = 200;
    const CODE_XML_READER_UNABLE_TO_READ = 201;
}

// Example usage
class CoreLib_Api_Reader
{
    protected function getReader()
    {
        $reader = new CoreLib_Api_Xml_Reader();

        if (!@$reader->open($this->getFileUri())) {

            $e = new CoreLib_Api_Exception(sprintf('Could not open %s for parsing', $this->getFileUri()), CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN);

            throw $e;
        }
    }
}

// Calling  code
try {

    $reader = CoreLib_Api_Reader();

    $reader->setFileUri($fileUri);
    $reader->getReader();

} catch (Exception $e) {

    // If code is anything other than open, throw it
    if ($e->getCode() !== CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN) {
        throw $e;
    }

    $e = null;

    $reader = null;
}

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

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

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