11

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.

halfer
  • 19,824
  • 17
  • 99
  • 186
Mubashar Abbas
  • 5,536
  • 4
  • 38
  • 49

3 Answers3

30

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.

wheelmaker
  • 2,975
  • 2
  • 21
  • 32
  • Do you always enable this? Or only in some cases? – Miguel Stevens Nov 23 '19 at 10:04
  • 1
    For me, this would just be to troubleshoot a test that's not working as expected. – wheelmaker Nov 24 '19 at 15:38
  • i think maybe add it as a snippet to your IDE to be temporarily used in methods when your test is failing and the error doesn't make sense – eballeste Aug 12 '20 at 20:35
  • See [here](https://chasingcode.dev/blog/laravel-withoutexceptionhandling-gotcha/) where Constantin notes that it may depend where you place it. Instead of always on top of the test method it may need to be right on top of the line of code you want to see the error for. I haven't tested this out but I have had cases where `withoutExceptionHandling` didn't print the error. – shmuels Mar 24 '21 at 17:37
3

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.

Valentine Shi
  • 6,604
  • 4
  • 46
  • 46
  • Answer https://stackoverflow.com/a/54411121/1768191 is the easiest and safest way to solve that problem with Laravel 5.5+ (see here: https://laravel-news.com/laravel-5-5) – mcbetz Sep 17 '19 at 11:12
  • @mcbetz, true. Though my answer is aimed more towards presenting the explanations how to solve the issues built in the original question to provide the basis for understanding how things work under the hood rather then give the copy-paste solution. – Valentine Shi Sep 20 '19 at 08:37
  • 1
    This is incredibly useful for Lumen. My previous workaround was to dd($response) individually, which was awful. Thanks! – Flayshon Jan 05 '20 at 00:35
  • 1
    @Flayshon, welcome. Sometimes using `dump($someThing)` would fit better if you want to continue the code execution after `var_dump()`. – Valentine Shi Jan 05 '20 at 02:56
1

my_projects\tests\TestCase.php | add fun

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

Handling all Exception

ali hassan
  • 321
  • 2
  • 5