How to pass a mock object into a class for unit tests

by nevada_scout   Last Updated May 17, 2018 12:05 PM

There seem to be many ways to pass a mocked object into a class for unit testing and I am unsure which is the proper approach to take for my PHP application.

If I was using Dependency Injection then I could have the dependencies as constructor arguments which I could use to pass mocks in from my tests:

class Example
{
    private $dependency;

    public function __construct(Dependency $dependency)
    {
        $this->dependency = $dependency;
    }
}

However, I'm not using Dependency Injection so I cannot use this approach.

Instead, I could add a public method to set the private property which is called from within the constructor:

class Example
{
    private $dependency;

    public function __construct()
    {
        $this->setDependency(new Dependency());
    }

    public function setDependency(Dependency $dependency)
    {
        $this->dependency = $dependency;
    }
}

My tests can now use this public method to set the dependency to my mocked value.
This seems like the best approach, however I've added this new setDependency method just to make testing easier and that feels a bit dirty.

Alternatively, I could use reflection to set the value of a protected property directly, but now my test needs knowledge of the implementation of the Example class:

class Example
{
    protected $dependency;
}

class ExampleTest
{
    public function testDependency()
    {
        $example = new Example();

        $dependencyMock = $this->getMock(); // Truncated

        $this->setPrivateProperty($example, "dependency", $dependencyMock);
    }
}

What is the right way for my tests to pass a mocked object into my Example class when I'm not using Dependency Injection?



Related Questions



Are HSQLDB unit tests an anti pattern?

Updated July 14, 2015 16:02 PM


Does integration testing use Mocks?

Updated April 18, 2017 14:05 PM