Magento 2, PHPUnit and magic methods

One can’t mock magic methods in PHPUnit, because of this error.

Trying to configure method “getTrackingSent” which cannot be configured because it does not exist, has not been specified, is final, or is static

So my workaround until now was to mock __call, like so:

$montonioShipment->method('__call')
    ->with('getTrackingSent', [])
    ->willReturn(1);

This is okay, if one needs only one or maybe two methods, but even with two this is already confusing, so I was always on the lookout to find a better solution.

And thanks to HAL McZus I just found a better one, thanks!

/** Mock Customer */

//Add a magic method to the list of mocked class methods
$methods = \array_merge(
    \get_class_methods(Customer::class),
    ['getCustomerType']
);

$this->customerModelMock = $this->getMockBuilder(Customer::class)
    ->setMethods($methods)
    ->disableOriginalConstructor()
    ->getMock();

//Now I can mock my magic method !
$this->customerModelMock->expects(static::any())
    ->method('getCustomerType')
    ->willReturn('professional');

But setMethods is deprecated, as of this pull request. Therefore we need a little more, so this is what I ended up with.

$shipment = $this->getMockBuilder(Shipment::class)
    ->addMethods(['getTrackingSent', 'setTrackingSent'])
    ->disableOriginalConstructor()
    ->getMock();
$shipment->expects($this->once())->method('setTrackingSent')->with(1);

Unfortunately this makes the only configurable methods the ones we provide with addMethods. So depending on the use case, one might want to mock better __call.

Leave a Reply