Ciaran McNulty
Ciaran McNulty

Reputation: 18868

Removing a dependency in a constructor using PHPunit

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

Answers (1)

Ionuț G. Stan
Ionuț G. Stan

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

Related Questions