I want to test the endpoints of my Slim application with PHPUnit. I’m struggling to mock POST requests (the request body is always empty).
I’ve tried the approach as described here: LINK_OMITTED. (adding the environment variable slim-input)
I’ve tried writing to php://input directly, but I’ve found out php://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.
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
My test code on github (be aware that I’ve simplified the code in the example): LINK_OMITTED
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.
I’m aware of this blog post, but unfortunately it uses the query parameters to submit the “infomation” rather than the body of a POST request.
PHPUnit is for testing purposes, its a framework which basically executes one test method at a time, and evaluates some assert statements. It therefore allows me to test some methods from my Slim application.
I’ve started using PHPUnit a bit, so I know what it is, but I’m just getting started. Perhaps a ping to @geggleto, @silentworks, @JoeBengalen r @akrabat as I bet one of them can help steer you in the right direction.
I’ve read now large parts of the source code (which is not that large to be honest), and I personally see no way this would work with the current set up. I’ve implemented the functionality with a new environment variable and will try my luck with a pull request today.
I’ve create a pull request for a patch which would enable the feature: https://github.com/slimphp/Slim/pull/2086
As there are some other open, unanswered pull requests it is probably gonna take some time till it gets accepted/rejected. Thanks for your help
Thanks! It needs some more time to setup, but nonetheless works better than my solution, as one does not need to introduce a new “magic” key into the environment. My solution:
It should be noted that this will NOT run middleware during unit testing, I had to:
$app->process($request, $response)
in order for jwt middleware to work, for example.