I have a PHPUnit test case directly deriving from PHPUnit_Framework_TestCase. In a test in this class I need to get a mock for some service object. This service object is of a type defined by an abstract base class. This base class holds both concrete and abstract methods. I want to get a full mock for the thing (ie all methods mocked out). My question is how to do this.
->getMock gives me an error since the abstract methods are not mocked, only the concrete ones
->getMockForAbstractClass mocks out the abstract methods but not the concrete ones
How do I mock them all out?
(I'm using PHPUnit 3.7.13)
Just calling ->getMock('Class');
will mock all the methods on an object and implement all the abstract methods.
I'm not really sure where you went wrong but since it's so, seemingly, straight forward I wrote a sample.
If it doesn't work out for you I'd need a reproduce case of what you are trying to do
<?php
class mockTest extends PHPUnit_Framework_TestCase {
// Without expectations
public function testMocking() {
$x = $this->getMock('MockMe');
$this->assertNull($x->foo());
$this->assertNull($x->bar());
}
// With expectations
public function testMocking2() {
$x = $this->getMock('MockMe');
$x->expects($this->once())->method('foo')->will($this->returnValue(true));
$x->expects($this->once())->method('bar')->will($this->returnValue(true));
$this->assertTrue($x->foo());
$this->assertTrue($x->bar());
}
}
abstract class MockMe {
abstract public function foo();
public function bar() {
return 1 + $this->foo();
}
}
PHPUnit 3.7.13 by Sebastian Bergmann.
..
Time: 0 seconds, Memory: 6.25Mb
OK (2 tests, 5 assertions)
It looks like $this->getMock(...) will fail for abstract classes if one or more of the abstract methods are not public.
If you don't want to use a derivative, you could add something like this to your test base class:
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 is adapted from: Mocking concrete method in abstract class using phpunit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With