# Mock Slim endpoint POST requests with PHPUnit

**URL:** <https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973>\
**Category:** Questions\
**Created:** [December 1, 2016, 9:22am UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973 "2016-12-01T09:22:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![famoser](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/famoser/32/273_2.png) [@famoser](https://discourse.slimframework.com/u/famoser)\
**Post date:** [December 1, 2016, 9:22am UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/1 "2016-12-01T09:22:12Z")

</div>

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’ve posted the exact same question to stackoverflow 2 days ago: [http://stackoverflow.com/questions/40867377/mock-slim-endpoint-post-requests-with-phpunit](http://stackoverflow.com/questions/40867377/mock-slim-endpoint-post-requests-with-phpunit). I hope you’re not mad about this, and I promise to keep both sites up to date 🙂 You’ll find there all the omitted links too
- I’d be very open for suggestions on how to improve the architecture of the application if something caches your attention

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [December 1, 2016, 3:42pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/2 "2016-12-01T15:42:55Z")

</div>

I’m quite inexperienced when it comes to PHPUnit, but have you read through [Testing Slim Framework Actions](https://akrabat.com/testing-slim-framework-actions/)?

---

<div class="post-metadata">

**Author:** ![famoser](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/famoser/32/273_2.png) [@famoser](https://discourse.slimframework.com/u/famoser)\
**Post date:** [December 1, 2016, 6:32pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/3 "2016-12-01T18:32:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![tflight](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tflight/32/1205_2.png) [@tflight](https://discourse.slimframework.com/u/tflight)\
**Post date:** [December 1, 2016, 6:57pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/4 "2016-12-01T18:57:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![famoser](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/famoser/32/273_2.png) [@famoser](https://discourse.slimframework.com/u/famoser)\
**Post date:** [December 2, 2016, 12:48pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/5 "2016-12-02T12:48:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![famoser](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/famoser/32/273_2.png) [@famoser](https://discourse.slimframework.com/u/famoser)\
**Post date:** [December 3, 2016, 3:10pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/6 "2016-12-03T15:10:07Z")

</div>

I’ve create a pull request for a patch which would enable the feature: [https://github.com/slimphp/Slim/pull/2086](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 🙂

---

<div class="post-metadata">

**Author:** ![geggleto](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/geggleto/32/11_2.png) [@geggleto](https://discourse.slimframework.com/u/geggleto)\
**Post date:** [January 24, 2017, 2:11pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/7 "2017-01-24T14:11:12Z")

</div>

I’m so sorry for being late to the party…

I had written something up for mocking Slim Requests… [http://glenneggleton.com/page/slim-unit-testing](http://glenneggleton.com/page/slim-unit-testing)  
Akrabat also has a page on it here… [https://akrabat.com/testing-slim-framework-actions/](https://akrabat.com/testing-slim-framework-actions/)

---

<div class="post-metadata">

**Author:** ![famoser](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/famoser/32/273_2.png) [@famoser](https://discourse.slimframework.com/u/famoser)\
**Post date:** [January 29, 2017, 10:23pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/8 "2017-01-29T22:23:33Z")

</div>

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:

```
//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('GET', $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());
```

---

<div class="post-metadata">

**Author:** ![geggleto](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/geggleto/32/11_2.png) [@geggleto](https://discourse.slimframework.com/u/geggleto)\
**Post date:** [March 6, 2017, 5:27pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/9 "2017-03-06T17:27:33Z")

</div>

My current solution is to just grab the Request object from the container, modify it then just pass it into whatever controller I am trying to test. 👍

---

<div class="post-metadata">

**Author:** ![tonegolf71](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/tonegolf71/32/381_2.png) [@tonegolf71](https://discourse.slimframework.com/u/tonegolf71)\
**Post date:** [April 26, 2017, 12:51pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/10 "2017-04-26T12:51:21Z")

</div>

For the record, I’ve followed [http://lzakrzewski.com/2016/02/integration-testing-with-slim/](http://lzakrzewski.com/2016/02/integration-testing-with-slim/) which is working really well for me.

---

<div class="post-metadata">

**Author:** ![travis](https://avatars.discourse-cdn.com/v4/letter/t/bbce88/32.png) [@travis](https://discourse.slimframework.com/u/travis)\
**Post date:** [November 29, 2017, 5:20pm UTC](https://discourse.slimframework.com/t/mock-slim-endpoint-post-requests-with-phpunit/973/11 "2017-11-29T17:20:39Z")

</div>

> [@famoser](#):
>
> //execute request  
> $app = new App();  
> $resOut = $app($request, new Response());

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.
