【问题标题】:PHPUnit assert no method is calledPHPUnit 断言没有调用任何方法
【发布时间】:2013-09-15 16:54:31
【问题描述】:
我有一个使用 ServiceB 的 ClassA。在某种情况下,ClassA 最终应该不会调用 ServiceB 的任何方法。我现在想测试一下,确实没有调用任何方法。
这可以按如下方式完成:
$classA->expects( $this->never() )->method( 'first_method' );
$classA->expects( $this->never() )->method( 'second_method' );
...
有没有办法简单地声明“不应该在这个对象上调用任何方法”,而不是必须为每个方法指定一个限制?
【问题讨论】:
标签:
php
unit-testing
testing
mocking
phpunit
【解决方案1】:
您还可以模拟一个方法和一个数据提供者,并确保它永远不会被调用。不做任何断言,因为它没有被调用,所以它已经通过了测试。
<?php
/**
* @dataProvider dataProvider
*/
public function checkSomethingIsDisabled( $message, $config, $expected)
{
$debugMock = $this->getMockBuilder('APP_Class_Name')
->disableOriginalConstructor()
->setMethods(array('_helper'))
->getMock();
$debugMock = $this->getPublicClass($debugMock);
$debugMock->_config = $config;
$viewContent = new stdClass;
$debugMock->_functionToTest($viewContent);
}
public function dataProvider()
{
return [
'dataset'=>
[
'message' => 'Debug Disabled',
'config' => (object) array(
'values' => (object) array(
'valueThatWhenFalseDoesntExecuteFunc'=> false
)
),
// in a probably needed complimentary "imaginary" test we probably
// will have the valueThatWhenFalseDoesntExecuteFunc set to true and on
// expected more information to handle and test.
'expected' => null
]
];
}
【解决方案2】:
您可以使用方法MockBuilder::disableAutoReturnValueGeneration。
例如,在您的测试中覆盖默认TestCase::getMockBuilder:
/**
* @param string $className
* @return MockBuilder
*/
public function getMockBuilder($className): MockBuilder
{
// this is to make sure, that not-mocked method will not be called
return parent::getMockBuilder($className)
->disableAutoReturnValueGeneration();
}
优点:
- 除了模拟方法之外,您的所有模拟都不会调用任何东西。无需将
->expects(self::never())->method(self::anything()) 绑定到所有这些
- 您仍然可以设置新的模拟。在
->expects(self::never())->method(self::anything()) 之后你不能
适用于 PhpUnit v7.5.4(可能还有更高版本)。
【解决方案3】:
是的,很简单,试试这个:
$classA->expects($this->never())->method($this->anything());