2

我正在尝试在 PHP 中测试捕获和处理自定义异常。

我用一些额外的属性和方法扩展了基本异常类型。

我存根的类之一可能会引发异常,我希望能够测试我是否正确捕获并处理了该异常(在这种情况下,这意味着构建一个响应对象以从调用中返回)。

例如

try {

    $objectBeingStubbed->doSomething();

} catch (\Exception $ex) {

    if ($ex instanceof CustomExceptionType) {

        $this->_errorResponse->error->message = $exception->getMessage();
        $this->_errorResponse->error->code = $exception->getCode();
        $this->_errorResponse->error->data = $exception->getData();

    } else {

        throw $ex;

    }

}

我试图模拟抛出的异常:

$objectStub->expects($this->any())
           ->method('doSomething')
           ->will($this->throwException(new CustomExceptionType()));

但是当异常到达我正在测试的类时,它现在是“Mock_ErrorResponse_????”的一个实例 这不会扩展我的自定义异常。我的异常包含在 Mock_ErrorResponse 的“$exception”属性中。

有什么方法可以处理这个问题而不会被迫做一些可怕的事情,比如:

if ($ex instanceof PHPUnit_Framework_MockObject_Stub_Exception) {
    $ex = $ex->exception;
}

if ($ex instanceof CustomExceptionType) {
...

在我正在测试的班级内?

4

2 回答 2

3

首先,改为:

} catch (\Exception $ex) {
    if ($ex instanceof CustomExceptionType) {

你应该使用 try/catch 结构:

    // (...)
} catch (CustomExceptionType $e) {
    // (...)
} catch (\Exception $e) {
    // (...)
}

所以,回答你的问题,基本上可能你做错了。因为当存根方法抛出异常时,它应该完全抛出您使用throwException方法设置的异常。

我不知道你是如何构建你的存根的(也许有什么东西坏了,也许是命名空间),但请考虑下面的一个例子,它工作得很好。

class Unit
{
    public function foo()
    {
        throw new \InvalidArgumentException();
    }

    public function bar()
    {
        try {
            $this->foo();
        } catch (\InvalidArgumentException $e) {
            return true;
        } catch (\Exception $e) {
            return false;
        }

        return false;
    }
}

class UnitTest extends \PHPUnit_Framework_TestCase
{
    public function testBar()
    {
        $sut = $this->getMock('Unit', array('foo'));
        $sut->expects($this->any())
            ->method('foo')
            ->will($this->throwException(new \InvalidArgumentException()));

        $this->assertTrue($sut->bar());
    }
}

当然,您可以InvalidArgumentException用自己的实现异常替换,这仍然应该有效。如果您仍然无法弄清楚代码有什么问题,请发布更完整的示例(例如,如何构建存根)。也许那时我可以提供更多帮助。

于 2013-02-26T10:55:57.033 回答
1

现在您可以使用 PHPUnit 中内置的 @expectedException php-doc 注释:https ://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.exceptions

/**
 * @expectedException InvalidArgumentException
 */
public function testBar()
{
    $sut = $this->getMock('Unit', array('foo'));
    $sut->expects($this->any())
        ->method('foo')
        ->will($this->throwException(new \InvalidArgumentException()));
}
于 2015-11-30T01:06:42.227 回答