Skip to main content

Mocking callables in an Expressive app

· 2 min read
Florian Horn

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
);

// ...