我应该创建自定义异常类型,以便我的代码更容易进行单元测试

时间:2012-01-31 23:46:27

标签: java unit-testing exception

在我的单元测试中,我测试了一个预期的RuntimeException方法,我希望将我的组件抛出的方法与方法中调用的代码抛出的方法区分开来。

创建自定义异常类型是不必要的,并且如果方法抛出相同的异常类型但由于不同的原因(例如, InvalidArgumentException。

看起来告诉他们的唯一方法是消息或错误代码。因为在开发过程中可以更改消息,所以错误代码似乎是唯一可靠的选项。

创建错误代码系统的最佳做法是什么,以便它们不与外部包的冲突,例如。第三方图书馆?

3 个答案:

答案 0 :(得分:1)

  

创建自定义异常类型是不必要的,并且无法解决问题   如果方法抛出相同的异常类型但不同的问题   原因,例如InvalidArgumentException。

为什么你认为这是不必要的?这是你应该做的。派生自己的自定义异常类,从代码中抛出实例并将其捕获到外部(在单元测试中)。可以在预期多个不同的异常类时重复catch语句:

try {
    // something
} catch (MySpecificException e) {
    // you know that your code threw this
} catch (Exception e) {
    // this is coming from somewhere else
}

答案 1 :(得分:0)

- 编辑 -

抱歉,我没有看到java标签。尽管以下示例使用PHP构造,但原则仍然适用。

- 原始 -

我仅在少数非常特殊的情况下使用自定义异常代码,并将这些代码存储在自定义异常类中,该异常类扩展了默认异常类。它们作为常量存储在类中,因为值并不重要,但上下文确实如此。

考虑:

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;
}

通过使用异常代码,我可以检查以确定读者是否无法打开文件,如果是,则忽略异常并继续,否则抛出异常并中断流程。

如果我的一个异常代码与第三方异常代码冲突,就像我之前提到的那样使用常量并不重要,上下文将指示我想要匹配的代码。

答案 2 :(得分:-1)

  

我测试了一个预期的RuntimeException方法

我认为这是一个错误。 RuntimeException仅应用于指示代码本身可以检测到的代码中的错误。测试应仅测试指定(定义)的行为。但是当某些代码中存在错误时,其行为是未定义的(谁知道错误可能在哪里或它可能做什么)。因此,尝试指定某些代码应该抛出的RuntimeException是没有意义的;这就像指定代码应该如何“存在bug”。将具有特定消息的特定RuntimeException投掷出来应被视为对维护程序员(可能是您)的礼貌。