Reputation: 787
I want to test this code block which has to call a static class.
class SomeModule {
public function processFoo()
{
$foo = FooFactory::getFoo();
// ... Do something to $foo
return $foo;
}
}
I can't modify the static class. I can however change the code inside the module. How can I refactor this code to be unit testable?
Upvotes: 6
Views: 252
Reputation: 787
Refactored code:
class SomeModule {
public function processFoo()
{
$foo = $this->getFoo();
$foo['hoopla'] = 'doo';
return $foo;
}
protected function getFoo()
{
return FooFactory::getFoo();
}
}
Test code:
function testSomeModule() {
// Whatever we want to simulate FooFactory::getFoo returning
$foo = array('woo' => 'yay')
// Create a copy of the class which mocks the method getFoo
$module = $this->getMockBuilder('SomeModule')
->setMethods(array('getFoo'))
->getMock();
// Rig the mock method to return our prepared sample
$module->expects($this->once())
->method('getFoo')
->will($this->returnValue($foo));
$result = $module->processFoo();
$this->assertEquals('yay', $result['woo']);
$this->assertEquals('doo', $result['hoopla']);
}
Upvotes: 4
Reputation: 787
Refactored code:
class SomeModule {
protected $factoryName;
public function __construct($factoryName = 'FooFactory') {
$this->factoryName = $factoryName;
}
public function processFoo()
{
// PHP Parser limitation requires this
$factoryName = $this->factoryName;
$foo = $factoryName::getFoo();
$foo['hoopla'] = 'doo';
return $foo;
}
}
Test code:
public class MockFactory {
static public function getFoo() {
return array('woo' => 'yay');
}
}
function testSomeModule() {
$module = new SomeModule('MockFactory');
$result = $module->processFoo();
$this->assertEquals('yay', $result['woo']);
$this->assertEquals('doo', $result['hoopla']);
}
Upvotes: 1