phpmockingphpunitslim

Php Slim framework unittest mock Router


I have created a wrapper for the Slim request in my application to have the ability to create some custom methods on the Request object.

class Request extends SlimRequest
{
    /**
     * Get authorization token.
     *
     * @return null|string
     */
    public function getAuthToken(): ?string
    {
        return $this->getHeaderLine('FOOBAR-TOKEN');
    }

    /**
     * Retrieves a route parameter.
     *
     * @param string $name
     * @return string|null
     */
    public function getRouteParam(string $name): ?string
    {
        return $this->getRoute()->getArgument($name);
    }

    /**
     * Retrieves the route instance.
     *
     * @return Route
     */
    public function getRoute(): Route
    {
        return $this->getAttribute('route');
    }
}

My problem comes when trying to create unit test for this class. The way I have been testing requests is by using Slims build in environment mocks. The first function I added a header to the request which can be seen below, but I can't figure out how to add a Route object to the request

$request = Request::createFromEnvironment(Environment::mock());
$request = $request->withHeader('FOOBAR-TOKEN', 'superSafeExampleToken');

I tried creating the request with a request options but $this->getAttribute('route'); returns null

$requestOptions = [
    'REQUEST_METHOD' => 'POST',
    'REQUEST_URI' => ' / foo / bar',
    'QUERY_STRING' => http_build_query($requestParameters),
];
$environment = Environment::mock($requestOptions);

Solution

  • Okay so the solution was the following

    public function testGetRouteParam()
    {
        $route = $route = new Route('GET', '/foo/{bar}', []);
        $route->setArguments(['bar' => 1]);
        $request = Request::createFromEnvironment(Environment::mock());
        $request = $request->withAttribute('route', $route);
    
        $this->assertEquals(1, $request->getRouteParam('bar'));
        $this->assertNull($request->getRouteParam('baz'));
    }