Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit: Don't report Symfony exceptions rendered to HTTP errors

I am running integration tests with PHPUnit (6.5.8, upgraded to 7.1.5, no difference) on an API built with Symfony (Flex 1.0).

I have several controllers that throw exceptions one way or the other, for example for security reasons (e.g. using the @IsGranted annotation).

Those exceptions get converted to JSON via the ExceptionController of the FOSRestBundle. This works fine, also in the tests.

I am testing those exceptions being converted by looking checking status codes, etc, example:

public function testSecurity() {
    $this->request('GET', '/foo');
    $this->assertStatusCode(403);
}

Now, this test does not fail and everything is working as it should, but PHPUnit still displays the following types of errors:

[error] Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException: "Access Denied by controller annotation @IsGranted("ROLE_ADMIN")" at /var/www/symfony/vendor/symfony/security/Http/Firewall/ExceptionListener.php line 117

While that doesn't affect the tests per se, as they still succeed, it is still rather bothering as these messages disrupt the output of the test run, making it harder to spot where actual errors occur. Ergo, I'd like to turn off these error messages. IMO, these Exceptions shouldn't be "uncaught", as they're evidently handled by some kind of handler, since they're converted to a JSON response.

What I've tried:

  • turning off error logging as mentioned in this issue describing exactly the behaviour I'm seeing
  • asserting a thrown Exception in PHPUnit, but this fails as the Exception is not actually thrown within the test
  • various PHPUnit settings (error_reporting, SHELL_VERBOSITY, APP_DEBUG, etc)

What I've noticed:

This only happens when the exception is thrown (e.g. due to use of @IsGranted). If I return the exception instead, PHPUnit does not show an error.

like image 895
Laura Avatar asked May 21 '18 20:05

Laura


1 Answers

I had the same problem. I'm assuming you're using BrowserKit for your functional tests.

My workaround was to check that the AccessDeniedException was thrown instead of checking that the status code was 403.

To get the exception, i disabled the BrowserKit exception catcher:

public function testSecurity()
{
    $this->expectException(AccessDeniedException::class);

    $client = static::createClient();
    $client->client->catchExceptions(false);

    $client->request('GET', '/foo');
}
like image 162
fxbt Avatar answered Sep 19 '22 17:09

fxbt