Mocking callables in an Expressive app
This blog post was published more than one year ago and might be outdated!
· 2 min read
While working with Zend Expressive, a PSR-7 middleware microframework, I wanted to apply some unit testing with a nice coverage to my middlewares. Middlewares are called by the __invoke method if you provide them as an object and not as a closure. The signature of the __invoke method looks like this:
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class FooMiddleware
{
public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response,
callable $next = null
): ResponseInterface;
}
Additionally, my middleware implementation does some stuff, but the middleware itself does not return a response, which is fine. Instead, my implementation calls the $next middleware in line, which looks like this:
public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response,
callable $next
): ResponseInterface {
// Doing the cool stuff
// Everything ends sometime
return $next($request, $response);
}
Now this has given me some questions on how to mock the $next argument while writing the unit test. Turns out, this is quite easy:
// ...
$callback = $this->createPartialMock(
\stdClass::class,
['__invoke']
);
$callback->expects($this->once())
->method('__invoke')
->with($serverRequest, $inputResponse)
->willReturn($outputResponse); // ResponseInterface
$fooMiddleware = new FooMiddleware();
$fooMiddlware(
$serverRequest, // ServerRequestInterface
$inputResponse, // ResponseInterface
$callback // callable
);
// ...