【问题标题】:Disable Laravel exception handling for Tests为测试禁用 Laravel 异常处理
【发布时间】:2018-11-12 08:05:26
【问题描述】:

我正在关注这门课程 testdrivenlaravel,它提到了一种禁用 Laravel 异常处理的方法,以防止 Laravel 处理发生的异常并抛出它,这样我们就可以得到更详细的错误我们的测试输出。

所以我在我的测试用例类中添加了这个方法,并且在渲染方法中我抛出了异常

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;
        }
    });
}

但是每当我在测试中调用它时,为了获得更详细的错误,我仍然会遇到 Laravel 处理程序正在呈现的相同错误。

当我像这样直接更改Handler 类时:

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

我得到了详细的错误信息,但我需要让 disableExceptionHandling 助手工作。

【问题讨论】:

    标签: laravel tdd


    【解决方案1】:

    在 2019 年,您尝试用 instance 方法替换的异常处理程序 App\Exceptions\Handler(参见 your_project\App\Exceptions\Handler)绑定在 Laravel IoC 容器中的 Illuminate\Contracts\Debug\ExceptionHandler::class 键处(参见 your_project/bootstrap/app.php 完成的地方)。

    要替换实际的处理程序,您必须使用默认绑定的相同 Illuminate\Contracts\Debug\ExceptionHandler::class 键重新绑定它,而不是您使用的 App\Exceptions\Handler。即:

    ... 在 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;
            }
        });
    }
    

    最后确保所有您在上述代码中引用的类在文件顶部有正确完全限定的命名空间提及。例如:

    use App\Exceptions\Handler;
    

    并确保您从测试中调用该方法。

    注意:上述的异常禁用方式非常适合 Lumen,因为 Lumen 中没有 Laravel 的实际 $this->withoutExceptionHandling() 方法(请参阅 this answer 中的更多详细信息)。

    【讨论】:

    • Answer stackoverflow.com/a/54411121/1768191 是使用 Laravel 5.5+ 解决该问题的最简单和最安全的方法(参见此处:laravel-news.com/laravel-5-5
    • @mcbetz,真的。虽然我的回答更多地旨在解释如何解决原始问题中内置的问题,以提供理解事物如何在幕后工作的基础,而不是提供复制粘贴解决方案。
    • 这对 Lumen 非常有用。我以前的解决方法是单独 dd($response),这很糟糕。谢谢!
    • @Flayshon,欢迎。如果您想在var_dump() 之后继续执行代码,有时使用dump($someThing) 会更合适。
    【解决方案2】:

    把它放在你的测试方法的顶部:

        $this->withoutExceptionHandling();
    

    您不需要为此创建方法,它包含在 laravel 的 'InteractsWithExceptionHandling' 特征中,您应该从测试中扩展抽象 TestCase 使用该特征。

    【讨论】:

    • 你总是启用这个吗?还是仅在某些情况下?
    • 对我来说,这只是为了解决无法按预期工作的测试。
    • 我想也许可以将它作为 sn-p 添加到您的 IDE 中,以便在您的测试失败并且错误没有意义时临时用于方法中
    • 参见here,Constantin 指出这可能取决于您放置它的位置。它可能需要位于您想要查看错误的代码行的顶部,而不是始终位于测试方法的顶部。我没有对此进行测试,但我遇到过withoutExceptionHandling 没有打印错误的情况。
    猜你喜欢
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-22
    • 2019-03-22
    相关资源
    最近更新 更多