Skip to content

Instantly share code, notes, and snippets.

@nesk
Created October 8, 2019 11:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nesk/3f324b1288f6472e8347bb3f207ca463 to your computer and use it in GitHub Desktop.
Save nesk/3f324b1288f6472e8347bb3f207ca463 to your computer and use it in GitHub Desktop.
How to mock an exception
<?php
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Firewall\AccessListener;
class ThrowerChecker
{
public function isThrownByFirewall(AccessDeniedException $exception): bool
{
// Walking through the stack frames and returning true if one of them is triggered by a specific class
foreach ($exception->getTrace() as $stackItem) {
$class = $stackItem['class'] ?? null;
if ($class === AccessListener::class) {
return true;
}
}
return false;
}
}
<?php
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Firewall\AccessListener;
class ThrowerCheckerTest extends TestCase
{
public function testIfExceptionsThrownByFirewallAreDetected(): void
{
$exception = new AccessDeniedException;
self::overrideExceptionTrace(
$exception,
[['class' => 'foo'],
['class' => AccessListener::class], ['class' => 'bar']]
);
}
/**
* Overrides an exception trace through reflection, since this cannot be done through mocking (getTrace is final).
*
* @param array<int, array<string, mixed>> $trace
*/
private static function overrideExceptionTrace(\Exception $exception, array $trace): void
{
$exceptionReflection = new \ReflectionObject($exception);
// Find the parent root to be able to read the "trace" property because it's defined on the \Exception class
while ($exceptionReflection->getParentClass() !== false) {
$exceptionReflection = $exceptionReflection->getParentClass();
}
$traceReflection = $exceptionReflection->getProperty('trace');
$traceReflection->setAccessible(true);
$traceReflection->setValue($exception, $trace);
$traceReflection->setAccessible(false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment