Florian Moser
Florian Moser

Reputation: 2663

Mock Slim endpoint POST requests with PHPUnit

I want to test the endpoints of my Slim application with PHPUnit. I'm struggling to mock POST requests, as the request body is always empty.

The emulation of the environment works correctly as for example the REQUEST_URI is always as expected. I've found out that the body of the request is read out in Slim\Http\RequestBody from php://input.

Notes:

my test code so far:

//inherits from Slim/App
$this->app = new SyncApiApp(); 

// write json to //temp, does not work
$tmp_handle = fopen('php://temp', 'w+');
fwrite($tmp_handle, $json);
rewind($tmp_handle);
fclose($tmp_handle);

//override environment
$this->app->container["environment"] =
    Environment::mock(
        [
            'REQUEST_METHOD' => 'POST',
            'REQUEST_URI' => '/1.0/' . $relativeLink,
            'slim.input' => $json,
            'SERVER_NAME' => 'localhost',
            'CONTENT_TYPE' => 'application/json;charset=utf8'
        ]
    );

 //run the application
 $response = $this->app->run();
 //result: the correct endpoint is reached, but $request->getBody() is empty

Whole project (be aware that I've simplified the code on stackoverflow): https://github.com/famoser/SyncApi/blob/master/Famoser.SyncApi.Webpage/tests/Famoser/SyncApi/Tests/

Note 2: I've asked at the slimframework forum, link: http://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973. I'll keep both stackoverflow and discourse.slimframework up to date what is happening.

Note 3: There is a currently open pull request of mine for this feature: https://github.com/slimphp/Slim/pull/2086

Upvotes: 6

Views: 4971

Answers (1)

Florian Moser
Florian Moser

Reputation: 2663

There was help over at http://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/7, the solution was to create the Request from scratch, and write to the request body.

//setup environment vals to create request
$env = Environment::mock();
$uri = Uri::createFromString('/1.0/' . $relativeLink);
$headers = Headers::createFromEnvironment($env);
$cookies = [];
$serverParams = $env->all();
$body = new RequestBody();
$uploadedFiles = UploadedFile::createFromEnvironment($env);
$request = new Request('POST', $uri, $headers, $cookies, $serverParams, $body, $uploadedFiles);

//write request data
$request->write(json_encode([ 'key' => 'val' ]));
$request->getBody()->rewind();
//set method & content type
$request = $request->withHeader('Content-Type', 'application/json');
$request = $request->withMethod('POST');

//execute request
$app = new App();
$resOut = $app($request, new Response());
$resOut->getBody()->rewind();

$this->assertEquals('full response text', $resOut->getBody()->getContents());

The original blog post which helped to answer was at http://glenneggleton.com/page/slim-unit-testing

Upvotes: 5

Related Questions