PHPUnit mock方法导致异常

PHPUnit mock方法导致异常,php,mocking,phpunit,Php,Mocking,Phpunit,我在一个类中有这个函数 public function doSomething() { try { $result = functionCall(); if ($result === true) { $this->doGoodResult('With Success Message'); } else { $this->doBadResult('ERROR - unable to

我在一个类中有这个函数

public function doSomething()
{
    try {
        $result = functionCall();
        if ($result === true) {
            $this->doGoodResult('With Success Message');
        } else {
            $this->doBadResult('ERROR - unable to do something');
        }
    } catch (Exception $e) {
        $this->doBadResult('Did you divide by zero?');
    }
}
我试图通过模拟额外的函数来测试它

public function test_doSomthingWithBadResultGetsDoBadResultCalled()
{
    $ajc = $this->getMockBuilder('MyClass')
        ->setMethods(array('doBadResult'))
        ->setConstructorArgs(array('doSomething', array('input_var' => 0)))
        ->getMock();
    $ajc->expects($this->once())
        ->method('doBadResult')
        ->willReturn(null)
        ->with($this->contains('ERROR - unable to do something'));
    $ajc->doSomething();
}
问题是我从PHPUnit得到了以下错误

MyClass::doBadResult('Did you divide by zero?') was not expected to be called more than once.
我不知道为什么,但看起来只有在这个模拟场景中才会执行catch语句


有人能帮我弄清楚为什么会发生这种情况,特别是如何设置它,使我的测试不会失败吗?

经过一些调试,我发现异常是为foreach()提供的
无效参数。
经过一些挖掘,它在
$this->contains('ERROR…')


答案是
$this->contains
应该是
$this->stringContains

以防止将来需要进行更多挖掘。代码中的一个问题是,您正在捕获基本异常类型

} catch (Exception $e) {
    $this->doBadResult('Did you divide by zero?');
}
当一个断言在PHPUnit中失败时,会抛出一个
PHPUnit\u Framework\u断言失败错误
,并被PHPUnit捕获。此错误扩展了基本PHP异常类。因此,在try块中,当调用mock对象时,它会检查所使用的参数。由于这些都不正确,它会抛出catch语句捕获的
PHPUnit\u Framework\u断言失败错误。然后调用你的mock上不希望调用的方法


正因为如此,您的测试最终可能会错误地通过。因为失败的断言会被代码捕获并处理。您应该有一个特定的异常,您的
catch
正在查找,并且任何其他异常都会传递到相应的级别。

这就是为什么在测试时检查特定异常类型很重要的原因。