Function Mocker new powers 01
January 16, 2015
Mocking interfaces with function-mocker.
Code to an interface
Be it a real interface
or an abstract
class type-hinting those in place of concrete classes is a good idea. Testing and mocking those dependencies is a possibility PHPUnit offers already. Given the client class below
class Client {
/**
* @var ObjectI
*/
protected $objectInterface;
/**
* @var AbstractObject
*/
protected $abstractObject;
public function setInterfaceObject(ObjectI $object) {
$this->objectInterface = $object;
}
public function setAbstractObject(AbstractObject $object) {
$this->abstractObject = $object;
}
public function useObjectInterface(){
$value = $this->objectInterface->method;
return $value * 10;
}
public function useAbstractObject(){
$value = $this->abstractObject->method();
return $value + 10;
}
}
and the two dependencies
interface ObjectI {
public function method();
}
abstract class AbstractObject {
abstract public function method();
public function anotherMethod();
}
then a test could be set up like this
public function test_calls_method_on_interface(){
$mockI = $this->geMock('ObjectI');
$mockI->expects($this->once())
->method('method')
->willReturn(23);
$sut = new Client();
$sut->setInterfaceObject($mockI);
$value = $sut->useObjectInterface()
$this->assertEquals(230, $value);
}
public function test_calls_method_on_interface(){
$mockAbstract = $this
->geMockBuilder('AbstractObject')
->disableOriginalConstructor()
->setMethods('method')
->getMockForAbstractObject();
$mockAbstract->expects($this->once())
->method('method')
->willReturn(23);
$sut = new Client();
$sut->setAbstractObject($mockAbstract);
$value = $sut->useAbstractObject()
$this->assertEquals(33, $value);
}
Function Mocker alternative
The test code above can be now rewritten using function-mocker in a shorter way
public function test_calls_method_on_interface(){
$mockI = FunctionMocker::replace('ObjectI::method', 23);
$sut = new Client();
$sut->setInterfaceObject($mockI);
$value = $sut->useObjectInterface()
$mockI->wasCalledOnce();
$this->assertEquals(230, $value);
}
public function test_calls_method_on_interface(){
$mockAbstract = FunctionMocker::replace('AbstractObject::method', 23);
$sut = new Client();
$sut->setAbstractObject($mockAbstract);
$value = $sut->useAbstractObject()
$mockAbstract->wasCalledOnce();
$this->assertEquals(33, $value);
}
Which slims down the tests a bit.
As always the magic happens in PHPUnit for the most part and its mocking engine.
Next
Trait replacement.