【问题标题】:Laravel: How to enable stacktrace error on PhpUnitLaravel:如何在 PhpUnit 上启用堆栈跟踪错误
【发布时间】:2017-06-16 04:24:40
【问题描述】:

我全新安装了 laravel 5.4

我尝试修改默认测试只是为了查看失败的测试。

测试/ExampleTest.php

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/ooops');

        $response->assertStatus(200);
    }
}

我期待看到更详细的错误,如 no route has been found or defined 等,但只是这个错误说

Time: 1.13 seconds, Memory: 8.00MB

There was 1 failure:

1) Tests\Feature\ExampleTest::testBasicTest
Expected status code 200 but received 404.
Failed asserting that false is true.

/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:51
/var/www/tests/Feature/ExampleTest.php:21

在没有有意义的错误的情况下进行 TDD 真的很难(是的,我知道在这种情况下 404 就足够了,但大多数情况下并非如此)。

有没有办法让堆栈跟踪与浏览器上显示的一样?或者至少更接近那个,以便我知道下一步我应该做什么。

提前致谢。

【问题讨论】:

    标签: laravel laravel-5 phpunit tdd laravel-5.4


    【解决方案1】:

    对于 Laravel 5.4,您可以使用 Adam Wathan 在 this gist 中提出的 disableExceptionHandling 方法(源代码如下)

    现在,如果您在测试中运行:

    $this->disableExceptionHandling();
    

    您应该获得可以帮助您找到问题的完整信息。

    对于 Laravel 5.5 及更高版本,您可以使用 Laravel 内置的 withoutExceptionHandling 方法

    Adam Wathan 的 gist 源代码

    <?php
    
    namespace Tests;
    
    use App\Exceptions\Handler;
    use Illuminate\Contracts\Debug\ExceptionHandler;
    use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
    
    abstract class TestCase extends BaseTestCase
    {
        use CreatesApplication;
    
        protected function setUp()
        {
            /**
             * This disables the exception handling to display the stacktrace on the console
             * the same way as it shown on the browser
             */
            parent::setUp();
            $this->disableExceptionHandling();
        }
    
        protected function disableExceptionHandling()
        {
            $this->app->instance(ExceptionHandler::class, new class extends Handler {
                public function __construct() {}
    
                public function report(\Exception $e)
                {
                    // no-op
                }
    
                public function render($request, \Exception $e) {
                    throw $e;
                }
            });
        }
    }
    

    【讨论】:

    • 非常感谢,现在正在显示堆栈跟踪。看来我必须在每种方法上调用它。我已经把它放在抽象的TestCase::setUp 方法上。有没有推荐的方法在每次测试中应用它?
    • @JaimeSangcap 实际上不是,我认为它应该在您测试错误时用作帮助程序,但是在运行实际测试时不应该使用它,因为它可能会改变结果和您的测试根据您的应用程序会出错,因此仅将其用作帮助您在测试中调试错误的助手,而不是作为测试的一部分
    • 是的,你是对的,即使没有disableExceptionHandling,它也会产生有意义的错误。感谢您指出这一点,这可能会节省我几个小时的头发拉扯时间;)
    • 在 Laravel 5.7 中方法是$this-&gt;withoutExceptionHandling();
    • 这对我很有用,我使用的是 Laravel 5.7,谢谢!
    【解决方案2】:

    如果你碰巧使用 Laravel 5.5 及更高版本,你可以使用内置方法:

    $this->withoutExceptionHandling();
    $this->withExceptionHandling();
    

    无论是在您的 setUp 方法中,还是在您的测试方法中。它们在以下trait中定义。

    为了快速而肮脏的调试,您还可以在response 对象上使用dump 方法:

    /** @test */
    public function it_can_delete_an_attribute()
    {
        $response = $this->json('DELETE', "/api/attributes/3");
    
        $response->dump()->assertStatus(200);
    
        $this->assertDatabaseMissing('table', [
            'id' => $id
        ]);
    
        ...
    }
    

    有一个 laracast 课程涵盖了这些细节。

    【讨论】:

    • $this->withoutExceptionHandling();在 Laravel 5.8 中似乎不起作用。我的代码抛出 500 并返回 Expected status code 200 but received 500.
    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 2018-09-19
    • 1970-01-01
    • 2011-08-25
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多