Have you solved the problem?
Catching abort() exception code with Laravel TestCase
Hi! I have simple middleware and i want to test it.
Middleware:
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user && $user->isAdmin()) {
return $next($request);
}
abort(403, 'You are not a site administrator!');
}
My test (it works):
public function testMiddlewareThrowsErrorForNonAdminUser()
{
$employer = factory(User::class)->create(['role' => User::EMPLOYER_ROLE]);
$request = new Illuminate\Http\Request();
$request->setUserResolver(function() use ($employer) {
return $employer;
});
$this->expectExceptionMessage('You are not a site administrator!');
$this->handleRequestWithMustBeAdminMiddleware($request);
}
protected function handleRequestWithMustBeAdminMiddleware($request) {
$middleware = new \App\Http\Middleware\MustBeAdmin();
$middleware->handle($request, function() {});
}
I'm sure i am missing smth about expectExceptionCode() function. Here i am trying to work with it:
public function testMiddlewareThrowsErrorForNonAdminUser()
{
$employer = factory(User::class)->create(['role' => User::EMPLOYER_ROLE]);
$request = new Illuminate\Http\Request();
$request->setUserResolver(function() use ($employer) {
return $employer;
});
$this->expectExceptionCode(403);
$this->handleRequestWithMustBeAdminMiddleware($request);
}
And i get in my console:
1) MustBeAdminTest::testMiddlewareThrowsErrorForNonAdminUser
Failed asserting that 0 is equal to expected exception code 403.
Laravel's abort() function for some reason returns 0 code. Why is it so ?
The answer lies in the Symfony\Component\HttpKernel\Exception\HttpException that is thrown. Look at it's constructor, the default $code = 0.
public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = array(), $code = 0)
Notice that $statusCode and the Exception $code are two different things.
If you must test the exception code, you could always rewrite the test like this
public function testMiddlewareThrowsErrorForNonAdminUser()
{
$employer = factory(User::class)->create(['role' => User::EMPLOYER_ROLE]);
$request = new Illuminate\Http\Request();
$request->setUserResolver(function() use ($employer) {
return $employer;
});
try {
$this->handleRequestWithMustBeAdminMiddleware($request);
} catch (\Throwable $e) {
}
$this->assertEquals(
new HttpException(403, 'You are not a site administrator!'),
$e
);
}
(Notice how the assertion is outside the catch, this will mean that if try doesn't throw an exception the test will still fail because $e is not defined.)
Please or to participate in this conversation.