Mubashar Abbas
Mubashar Abbas

Reputation: 5673

Disable Laravel exception handling for Tests

I am following along this course testdrivenlaravel, and it mentions a way disable the Laravel's exception handling to prevent Laravel from handling exceptions that occur and instead throwing it, so we can get a more detailed error in our tests output.

So I added this method in my testcase class, and in the render method I am throwing the exception

protected function disableExceptionHandling() {

    $this->app->instance(Handler::class, new class extends Handler {
        public function __construct()
        {
        }
        public function report(\Exception $e)
        {
        }
        public function render($request, \Exception $e)
        {
            throw $e;
        }
    });
}

But whenever I call it in a test, to get more detailed error, I still get the same errors that Laravel Handler is rendering.

When I change the Handler class directly like this:

public function render($request, Exception $exception)
{
    throw $exception;
    // return parent::render($request, $exception);
}

I get the detailed errors, but I need to get the disableExceptionHandling helper work.

Upvotes: 11

Views: 18303

Answers (3)

ali hassan
ali hassan

Reputation: 459

my_projects\tests\TestCase.php | add fun

public function setUp(): void
{
    parent::setUp();
    $this->withoutExceptionHandling();
}

Handling all Exception

Upvotes: 2

Valentine Shi
Valentine Shi

Reputation: 7848

In 2019 the exception handler App\Exceptions\Handler (see your_project\App\Exceptions\Handler) you try to replace with instance method is bound in the Laravel IoC container at Illuminate\Contracts\Debug\ExceptionHandler::class key (see your_project/bootstrap/app.php where it is done).

To replace the actual handler you have to rebind it using the same Illuminate\Contracts\Debug\ExceptionHandler::class key it was bound to by default, not App\Exceptions\Handler you use. I.e.:

... in your_project/tests/TestCase.php

public function disableExceptionHandling()
{
    $this->app->instance(\Illuminate\Contracts\Debug\ExceptionHandler::class, new class extends Handler
    {
        public function render($request, \Exception $e)
        {
            throw $e;
        }
    });
}

Finally ensure that all the classes you are referencing from within your code above have correct fully qualified namespaced mentions at the top of the your file. E.g.:

use App\Exceptions\Handler;

And ensure that you are calling the method from your test.

NB: The above way of exception disabling is great for Lumen since there is no Laravel's actual $this->withoutExceptionHandling() method (see a bit more details in this answer) available in Lumen.

Upvotes: 3

whmkr
whmkr

Reputation: 3085

Put this at the top of your test method:

    $this->withoutExceptionHandling();

You don't need to create a method for this, it's included in laravel's 'InteractsWithExceptionHandling' trait which is used by the abstract TestCase that you should be extending from your test.

Upvotes: 31

Related Questions