PHPUnit Mock对象默认情况下不会期望任何东西

9
有没有办法告诉phpunit模拟对象,如果没有明确定义的期望,就永远不要期望方法调用?

“从“永远不要期望”这个说法中,你的意思是什么?” 我理解的是,如果模拟对象调用了未明确期望的方法,测试应该始终失败。这正确吗? - Cyprian
是的,没错。我不想为每个不应该被调用的方法编写 $mock->expects($this->never())->method('abc') - Bakyt Abdrasulov
3个回答

15
在我看来,对于每个方法都不抱有期望并不是一个好主意。因此,phpunit没有任何功能。只有在你想完全确保某个方法不会被调用时,才应该使用“never”期望。
无论如何,您可以使用一些匹配器来实现您的目标。例如:
所有对象方法的“never”期望(如果调用任何模拟方法,则失败):
$mock->expects($this->never())
    ->method($this->anything());

因此,例如您可以测试某个对象不会调用除被测试的方法之外的任何方法:
$mock = $this->getMock('Some\Tested\Class', array('testedMethod'));
$mock->expects($this->never())
    ->method($this->anything());

你也可以尝试使用另一个匹配器,例如matchesRegularExpression:
$mock->expects($this->never())
    ->method($this->matchesRegularExpression('/get.*/'));

例如上述代码,如果调用任何getter方法都会导致失败。
我知道这并不完全符合您的要求,但恐怕在phpunit中没有这样的解决方案。

1
太棒了,我不知道你可以为方法名称指定正则表达式。这样我就可以说expected($this->never())->method('|^goodMethod|'),意思是它不应该期望调用任何方法,除了叫做goodMethod()的那个。虽然不完全符合OP的要求,但解决了我的问题。 - rodrigo-silveira

1
如果您想测试在给定特定参数时方法从未被调用,可以使用:
$mock->expects($this->any())
->method('foo')
->with(new PHPUnit_Framework_Constraint_Not('bar'));

0
从PHPUnit 7.2开始,您可以使用类似问题的此答案。为了使所有意外的模拟方法调用导致失败,请重写TestCase::getMockBuilder()方法。
public function getMockBuilder(string $className): MockBuilder
{
    return parent::getMockBuilder($className)->disableAutoReturnValueGeneration();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接