php - 在PHPUnit中,对实现给定接口的模拟对象的未定义方法?

  显示原文与译文双语对照的内容
0 0

我熟悉单元测试和PHPUnit 。

我需要一个模拟,我对其具有完全控制权,实现 ConfigurationInterface接口。 测试对象的 ReportEventParamConverter对象之间的交互和测试必须检查我的对象和接口。

ReportEventParamConverter对象( 简体) 如下:

class ReportEventParamConverter implements ParamConverterInterface
{
    /**
     * @param Request $request
     * @param ConfigurationInterface $configuration
     */
    function apply(Request $request, ConfigurationInterface $configuration)
    {
        $request->attributes->set($configuration->getName(), $reportEvent);
    }
    /**
     * @param ConfigurationInterface $configuration
     * @return bool
     */
    function supports(ConfigurationInterface $configuration)
    {
        return 'MyNamespacedClass' === $configuration->getClass();
    }
}

正需要这样我想mock的接口:

$cls = 'SensioBundleFrameworkExtraBundleConfigurationConfigurationInterface';
$mock = $this->getMock($mockCls);

我需要对返回的值为两个方法: getClass()getName(). 例如:

$mock->expects($this->any())
    ->method('getClass')
    ->will($this->returnValue('SomeOtherClass'))
;

当我创建一个新的 ReportEventParamConverter和测试 supports()方法时,得到类似如下PHPUnit错误:

致命错误: 调用未定义的方法Mock_ConfigurationInterface_21e9dccf::getClass( ) 。

$converter = new ReportEventParamConverter();
$this->assertFalse($converter->supports($mock));
时间:原作者:8个回答

0 0

这是因为没有声明" getClass " 方法在ConfigurationInterface 。 此接口中唯一声明的方法" getAliasName " 。

你只需要告诉系统将stubing模拟什么方法:

$cls = 'SensioBundleFrameworkExtraBundleConfigurationConfigurationInterface';
$mock = $this->getMock($mockCls, array('getClass', 'getAliasName'));

请注意,没有" getClass " 声明可以stub/mock非现有方法同样重要。 在你身边可以模拟它:

$mock->expects($this->any())
    ->method('getClass')
    ->will($this->returnValue('SomeOtherClass'));

但是在加法指令需要mock " getAliasName " 方法也只要是接口方法或抽象有且必须要" 实现" 。 eg .:

$mock->expects($this->any())
   ->method('getAliasName')
   ->will($this->returnValue('SomeValue'));
原作者:
0 0

cyprian的回答帮助我,但有点明白了需要注意的。 可以mock的类不存在,PHPUnit不会抱怨。 所以你可以做

$mock = $this->getMock('SomeClassThatDoesntExistOrIsMisspelledOrPerhapsYouForgotToRequire');

这意味着,如果 ConfigurationInterface不存在那时仍在运行时,你将得到以下消息

致命错误: 调用未定义的方法Mock_ConfigurationInterface_21e9dccf::getClass( ) 。

如果确实真的存在于该类的方法,则可能出现的问题是类本身不存在( 因为你不需要它,或者你把它拼写错等) 。


OP是使用接口 。 请注意,你必须调用 getMock而无需指定要重写的方法的列表,或者如果你这样做,你必须传递 array()或传递所有方法名,否则将出现错误如下:

php致命错误: 类Mock_HttpRequest_a7aa9ffd包含4 个抽象方法,因此必须是声明为抽象或实现其余的方法( HttpRequest::setOption,httprequest::execute httprequest::getinfo,- - )

原作者:
0 0

泰勒Collier为warning尚可但不包含代码段有关如何代码周围。 注释该操作是非常难看的并且你应该修复该接口代替。 与该警告说,

$methods = array_map(function (ReflectionMethod $m) { return $m->getName();}, (new ReflectionClass($interface))->getMethods());
$methods[] = $missing_method;
$mock = $this->getMock($interface,  $methods);
原作者:
...