在phpUnit中模拟异常

时间:2017-11-28 09:01:49

标签: php mocking phpunit

我尝试测试的方法有一个类似

的尝试
try {
    $fooClass->doStuff(); // Throws \Lib\Custom\Exception
} 
catch (\Lib\Custom\Exception $exception) {
    return false;
}

我想测试返回是否为false,但是在执行测试时未加载自定义异常。

Php单位可以选择模拟类,但我似乎无法将其用于例外。

$exceptionMock= $this->getMockBuilder(\Lib\Custom\Exception::class)->getMock();

$fooClassMock = $this->getMockBuilder(fooClass::class)->getMock()
     ->method('doStuff')
     ->willThrowException($exceptionMock);

给我以下例外:

Argument 1 passed to 
PHPUnit_Framework_MockObject_Builder_InvocationMocker::willThrowException() 
must be an instance of Exception, instance of Mock_Exception_c4dd9394 given

如何正确模拟此Exception以测试函数?

2 个答案:

答案 0 :(得分:3)

我认为你不需要嘲笑例外。

为什么不尝试这个?

$fooClassMock = $this->getMockBuilder(fooClass::class)->getMock()
     ->method('doStuff')
     ->willThrowException(new \Lib\Custom\Exception());

或类似的东西..

答案 1 :(得分:1)

您的测试不起作用的原因是因为测试中不知道该类。当发生这种情况并在PHPUnit中创建一个模拟时,它会创建一个类定义,然后扩展它以创建模拟。否则它将使用扩展类本身,你不会遇到问题。

在这种情况下,PHPUnit会创建一个假的\Lib\Custom\Exception,然后使用它来创建模拟。创建的假类没有扩展任何东西(因为它不知道扩展/实现什么)。因此,willThrowException中的类型提示将不会匹配,因为您的模拟对象未扩展Exception

如果在测试中没有加载类,那么在PHPUnit中提示扩展类的任何类型都会发生这种情况。为了解决这个问题,您需要通过require,include或autoloader在测试中使用该类。