Reputation: 18868
While trying to get a legacy codebase under test, I've come across an object that does the following:
class Foo
{
public function __construct($someargs)
{
$this->bar = new Bar();
// [lots more code]
}
}
Bar in this instance has a constructor that does some Bad Things e.g. connecting to a database. I'm trying to concentrate on getting this Foo class under test so changed it to something like this:
class Foo
{
public function __construct($someargs)
{
$this->bar = $this->getBarInstance();
// [lots more code]
}
protected function getBarInstance()
{
return new Bar();
}
}
And have attempted to test it via the following PHPUnit test:
class FooTest extends PHPUnit_Framework_TestCase
{
public function testInstance()
{
$bar = $this->getMock('Bar');
$foo = $this->getMock('Foo', array('getBarInstance'));
$foo->expects($this->any())
->method('getBarInstance')
->will($this->returnValue($bar));
}
}
However this doesn't work - the constructor of Foo() is called before my ->expects() is added, so the mocked getBarInstance() method returns a null.
Is there any way of unlinking this dependency without having to refactor the way the class uses constructors?
Upvotes: 2
Views: 1843
Reputation: 179179
Use the $callOriginalConstructor
argument of getMock()
. Set it to false
. It's the fifth argument of the method. Look it up here: http://www.phpunit.de/manual/current/en/api.html#api.testcase.tables.api
Actually, hold on. You want to pass a mock to a mock? If you really want this, then use the third argument of getMock
which represents the arguments to the constructor. There you can pass the mock of Bar
to the mock of Foo
.
Upvotes: 4