PHPUnit模拟抽象类的所有方法

PHPUnit模拟抽象类的所有方法,php,unit-testing,testing,mocking,phpunit,Php,Unit Testing,Testing,Mocking,Phpunit,我有一个PHPUnit测试用例,它直接来自PHPUnit_框架_测试用例。在这个类中的测试中,我需要为某个服务对象获取一个模拟。此服务对象属于抽象基类定义的类型。这个基类同时包含具体方法和抽象方法。我想对这件事进行一次全面的模拟(即模拟出所有的方法)。我的问题是如何做到这一点 ->getMock给了我一个错误,因为抽象方法不是模拟的,而是具体的方法 ->getMockForAbstractClass模拟抽象方法,但不模拟具体方法 我怎么才能把他们都嘲弄出来呢 (我正在使用phpunit3.7.1

我有一个PHPUnit测试用例,它直接来自PHPUnit_框架_测试用例。在这个类中的测试中,我需要为某个服务对象获取一个模拟。此服务对象属于抽象基类定义的类型。这个基类同时包含具体方法和抽象方法。我想对这件事进行一次全面的模拟(即模拟出所有的方法)。我的问题是如何做到这一点

->getMock给了我一个错误,因为抽象方法不是模拟的,而是具体的方法

->getMockForAbstractClass模拟抽象方法,但不模拟具体方法

我怎么才能把他们都嘲弄出来呢


(我正在使用phpunit3.7.13)

只是调用
->getMock('Class')
将模拟对象上的所有方法并实现所有抽象方法

我真的不确定你哪里出了问题,但因为这看起来很简单,我写了一个样本

如果这对你不起作用,我需要一个你想做什么的复制案例

样品
如果一个或多个抽象方法不是公共的,那么对于抽象类,$this->getMock(…)将失败

如果您不想使用派生,可以向测试基类中添加如下内容:

protected function getMockOfAbstractClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) {
    if ($methods !== null) {
        $methods = array_unique(array_merge($methods,
        $this->getMethods($originalClassName, $callAutoload)));
    }
    return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload);
}

private function getMethods($class, $autoload=true) {
    $methods = array();
    if (class_exists($class, $autoload) || interface_exists($class, $autoload)) {
        $reflector = new ReflectionClass($class);
        foreach ($reflector->getMethods( ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_ABSTRACT ) as $method) {
            $methods[] = $method->getName();
        }
    }
    return $methods;
}

这是改编自:

我正在做$This->getMock('SomeAbstractClass')。获取:致命错误:类Mock_SomeAbstractClass_cbc14c8a包含2个抽象方法,因此必须在/usr/share/php/PHPUnit/Framework/MockObject/Generator.php(231):eval()中声明为抽象或实现其余方法(SomeAbstractClass::foo,SomeAbstractClass::bar)第3302行的d代码有趣的是,您的示例代码对我来说确实很好。在我的例子中,抽象类非常复杂,并且实现了一些接口。也许它在PHPUnit中引起了一些bug?我现在的解决方法是在getMock方法调用中引用它的一个派生函数,当然这总是可能的。或者,它可能无法找到/加载其中一个接口,也无法事先找出方法(或其他!)。如果您可以用代码重现错误,并且可以共享一个bug报告,那么肯定会受到欢迎:)这已经在PHPUnit的后续版本中实现了,如本答案中所述。
PHPUnit 3.7.13 by Sebastian Bergmann.

..

Time: 0 seconds, Memory: 6.25Mb

OK (2 tests, 5 assertions)
protected function getMockOfAbstractClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) {
    if ($methods !== null) {
        $methods = array_unique(array_merge($methods,
        $this->getMethods($originalClassName, $callAutoload)));
    }
    return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload);
}

private function getMethods($class, $autoload=true) {
    $methods = array();
    if (class_exists($class, $autoload) || interface_exists($class, $autoload)) {
        $reflector = new ReflectionClass($class);
        foreach ($reflector->getMethods( ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_ABSTRACT ) as $method) {
            $methods[] = $method->getName();
        }
    }
    return $methods;
}