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.
- I've tried the approach as described here: Slim Framework endpoint unit testing. (adding the environment variable
slim-input
) - I've tried writing to
php://input
directly, but I've found outphp://input
is read only (the hard way)
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:
- I want to avoid calling the controller methods directly, so I can test everything, including endpoints.
- I want to avoid
guzzle
because it sends an actual request. I do not want to have a server running while testing the application.
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