there4/slim-test-helpers

How to test 'Internal Server Error' from a LocalWebTestCase

Starli0n opened this issue · 6 comments

Hi,

I would like to test an 'Internal Server Error' from a LocalWebTestCase but I do not know how to do it.

First I added this error handler in SlimApp:

// Error handler
$container['errorHandler'] = function ($c) {
    return function ($request, $response, $exception) use ($c) {
        $c->logger->error('Internal Server Error');
        $data = array('message' => 'Internal Server Error');
        return $c['response']->withJson($data, 500);
    };
};

I added a specific route only for testing purpose:

// Route for testing server internal error (ie: $container['errorHandler'])
$app->get('/internalerror', function ($request, $response, $args) {
    $this->logger->info("Route '/' internalerror");
    throw new \Exception('Testing /internalerror.');
    return $response;
});

In a test case I do:

public function testInternalError()
{
    try {
        $this->client->get('/internalerror');
    } catch (\Exception $e) {
    }
    $response = $this->client->response;
    $this->assertEquals(500, $response->getStatusCode());
    $this->assertEquals('Internal Server Error', $response->getReasonPhrase());
    $this->assertEquals('application/json;charset=utf-8', $response->getHeader('Content-Type')[0]);
    $data = json_decode($response->getBody());
    $this->assertEquals('Internal Server Error', $data->message);
}

But $this->client->response return null.

My aim would be to test the message sent by the server defined in the error handler.

In a production environment, this route is working fine and I have the message 'Internal Server Error' in json.

http://localhost:8080/internalerror

{"message":"Internal Server Error"}

Thanks for your help!

That's some very thorough integration testing. I haven't tried this, and I'm not entirely sure what is going on.

What version of Slim are you using?

I am using the V3.

Actually I found the fix. In there4/slim-test-helpers/src/There4/Slim/Test/WebTestClient.php:105:

Replace invoke:

    // Invoke request
    $app = $this->app;
    $this->response = $app($this->request, $response);

By process:

    // Process request
    $app = $this->app;
    $this->response = $app->process($this->request, $response);

Therefore Slim would handle the exception in slim/slim/Slim/App.php:339

    // Traverse middleware stack
    try {
        $response = $this->callMiddlewareStack($request, $response);
    } catch (Exception $e) {
        $response = $this->handleException($e, $request, $response);
    } catch (Throwable $e) {
        $response = $this->handlePhpError($e, $request, $response);
    }

I tested, the testInternalError() works fine now.

Could you please fix it in a new release ?

@Starli0n Thanks for the report! If you have time, can you send a PR for this fix? I'd like to add you as a contributor. Thanks!

Fix found in pull request #35.
Thank you so much!

As a side note, the mentioned PR also fixed a problem I had with App Middleware not being executed. Thanks 👍

@Starli0n : I added a short release description on https://github.com/there4/slim-test-helpers/releases , feel free to edit it if you can phrase this better :)