How to write tests when closures are involved
To mock callables, I usually mock __invoke
:
$callbackMock = $this->getMockBuilder(\stdClass::class)
->setMethods(['__invoke'])
->getMock();
$callbackMock->expects($this->once())->method('__invoke'); // etc.
The problem is that Magento uses \Closure
type hints instead of callable
. As soon as Magento supports PHP 7.1 you will be able to use Closure::fromCallable($callbackMock)
, until then, wrap it yourself:
$closure = function(...$args) use ($callbackMock) {
return $callbackMock(...$args);
};
That aside, I would not bother writing unit tests for plugins most of the time. If there is business logic that I write with unit tests, this would be in another class where the plugin delegates to. To test if the plugin works correctly, an integration test is more appropiate.