我正在尝试在PHP中测试捕获和处理自定义异常。
我已经使用一些额外的属性和方法扩展了基本异常类型。
我正在存根的其中一个类可以抛出异常,我希望能够测试我正确捕获和处理该异常(在这种情况下意味着构建一个响应对象以从调用返回)。
e.g。
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) {
...
在课堂上我正在测试?
答案 0 :(得分:3)
首先,改为:
} catch (\Exception $ex) {
if ($ex instanceof CustomExceptionType) {
你应该使用try / catch结构:
// (...)
} catch (CustomExceptionType $e) {
// (...)
} catch (\Exception $e) {
// (...)
}
所以,回答你的问题,基本上你可能做错了。因为当stubbed方法抛出异常时,它应该抛出你用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
替换为您自己的实现异常,但这仍然有用。如果您仍然无法弄清楚代码有什么问题,请发布更完整的示例(例如,如何构建存根)。也许那时我可以提供更多帮助。
答案 1 :(得分: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()));
}