PHPUnit:如何获取导致PHPUnit_Framework_Error_Warning的ORIGINAL异常

时间:2015-06-01 14:16:29

标签: php exception exception-handling phpunit

我正在编写一个PHPUnit测试(v4.6.7),用于处理XML的新PHP类(v5.3.3)。测试的目的是确认类在处理错误的XML时抛出DOMException。

我想收集异常并对其执行assertInstanceOf,并将其与DOMException进行比较。

无论我做什么,当我看到异常时,phpunit已经将原始异常转换为PHPUnit_Framework_Error_Warning的实例。

例如,以下是测试代码中的一项工作:

//...
try {
    $this->code_that_causes_exception();
} catch (\Exception $exception) {
    $className = get_class($exception);
    throw $exception;
}
//...

从phpunit中运行时,$ className中存储的字符串为PHPUnit_Framework_Error_Warning,而不是code_that_causes_exception实际引发的异常。

开始更新

为了澄清我的问题,在测试代码中没有try / catch,phpunit报告的消息是DOMDocument::loadXML(): Start tag expected, '<' not found in Entity, line: 1。我做了一个大概的假设,即DOMDocument正在抛出某种异常来产生这个消息。 DOMDocument表示DOMException是从DOMDocument对象抛出的异常的父级。

结束更新

我想要原始异常,以便我可以使用适当的try / catch包装正在测试的代码,以便优雅地处理这种失败情况。 如何获取PHPUnit_Framework_Error_Warning实例化的原始例外?

1 个答案:

答案 0 :(得分:3)

为什么会这样?

您的例外未转换PHPUnit_Framework_Error_Warning永不抛出。 PHPUnit自动将 PHP警告转换为异常。这是由XML配置文件中的convertWarningsToExceptions属性启用的(分别还有convertNoticesToExceptionsconvertErrorsToExceptions)。默认情况下,所有这些设置均为true

这意味着您的原始异常可能永远不会被抛出,因为PHP警告会在之前触发,然后由PHPUnit的错误处理程序转换为(瞬间抛出的)异常。

仔细查看捕获的异常,看看代码中的哪个语句触发了PHP警告(只需删除try / catch语句,让PHPUnit呈现误差)。

您可以在phpunit.xml文件中禁用此行为:

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.6/phpunit.xsd"
     ...
     convertErrorsToExceptions="false"
     convertNoticesToExceptions="false"
     convertWarningsToExceptions="false"
     ...

应如何测试异常

断言抛出特定异常的最简单方法是使用@expectedException注释。这是讨论in-depth in the manual。使用此注释可以为您节省大量的样板代码:

/**
 * @expectedException DOMException
 * @test
 */
public function myTestCase() {
    $this->code_that_causes_exception();
}

DOMException被抛出时,会传递,并且当没有抛出任何异常(或者抛出任何其他异常)时会失败。