PHPUnit Quick Tip - Type Hint Your Mocks Posted on February 6th, 2017
Whenever I create a new test, I tend to follow the same format. Create a setUp
method, declare all my mocks. Then inject the mocks into the unit of code I'm testing. My IDE's static code analyzer would always complain about parameter type mismatches. Mainly, that I was supplying instances of MockObject
rather than *Interface
. Fortunately, I came across a nice solution that fixed the analyzer warnings as well as preserved my IDE auto completion.
<?php
namespace Acme\Project;
use GuzzleHttp\Client;
use PHPUnit_Framework_TestCase;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
class ApiWrapperTest extends PHPUnit_Framework_TestCase
{
/** @var Client|MockObject */
protected $http;
/** @var ApiWrapper */
protected $client;
public function setUp()
{
$this->http = $this->createMock(Client::class);
$this->wrapper = new ApiWrapper($this->http);
}
}
There are two important changes here. I've included the aliased namespace, PHPUnit_Framework_MockObject_MockObject as MockObject
. This makes my docblock type hints easier to read. Next, I've specified that my mock objects are not only instances of MockObject
but also of their mocked class, Client|MockObject
. This means the property can either be an instance of Client
or MockObject
. My IDE's static code analyzer no longer complains about parameter type mismatches and I still have code completion for my mock.
I haven't memorized the MockObject namespace for PHPUnit, instead I've created a PHPStorm Live Template, basically a macro. Anytime I type um↹, my IDE will print use PHPUnit_Framework_MockObject_MockObject as MockObject
to the screen. This was enough to do and the steps taken can be seen in the image below: