【问题标题】:Handling Laravel HttpException in Unit Testing在单元测试中处理 Laravel HttpException
【发布时间】:2014-02-28 14:07:13
【问题描述】:

我在 Laravel 中进行单元测试的一个测试函数不断出错。我试图断言在不满足某些条件的情况下请求特定页面会触发 403 FORBIDDEN 错误。

我的测试用例函数是这样的:

public function testNoAjaxCall() {

    $this->call('POST', 'xyz', array());

    $this->assertResponseStatus(403);

}

在路由到的控制器动作中,我有这个:

if(!Input::has('ajax') || Input::get('ajax') != 1) {

    // Drop all 'non-ajax' requests.
    App::abort(403, 'Normal POST requests to this page are forbidden. Please explicitly tell me you\'re using AJAX by passing ajax = 1.');

}

运行 phpunit 返回以下内容:

1) RaceTest::testNoAjaxCall

Symfony\Component\HttpKernel\Exception\HttpException:禁止对该页面的正常 POST 请求。请通过传递 ajax = 1 明确告诉我您正在使用 AJAX。

[路径\to\laravel]\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:875

[编辑的堆栈跟踪]

[路径\to\laravel]\vendor\symfony\http-kernel\Symfony\Component\HttpKernel\Client.php:81

[路径\to\laravel]\vendor\symfony\browser-kit\Symfony\Component\BrowserKit\Client.php:325

[路径\to\laravel]\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestCase.php:74

[路径\to\laravel]\app\tests[testFileName].php:176

失败!

测试:6,断言:17,错误:1。

当然堆栈跟踪指向$this->call(..);App::abort(..)

我的 app/start/global.php 文件中有一个 HttpException 错误处理程序,它在单元测试之外触发它时有效(例如,直接向测试的 URL 发出 POST 请求),但单元测试似乎没有正确捕获异常甚至到达断言调用。

我错过了什么?

【问题讨论】:

    标签: php unit-testing symfony laravel laravel-4


    【解决方案1】:

    http://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.expectedException应该已经解释过了。

    /**
     * @expectedException \Symfony\Component\HttpKernel\Exception\HttpException
     * @expectedExceptionMessage Normal POST requests to this page are forbidden. Please explicitly tell me you\'re using AJAX by passing ajax = 1.
     */
    public function testNoAjaxCall() {
    
        $this->call('POST', 'xyz', array());
    
    }
    

    【讨论】:

    • 这确实有效,这要归功于 PHP Unit 的内置解析器。这很奇特,因为 Laravel 提供了自己的断言辅助方法,如果无法访问它们似乎是无用的。 (laravel.com/docs/testing#framework-assertions)
    【解决方案2】:

    到目前为止,我发现断言 HttpException 状态代码的最佳方法可以在 sirbarrence 的工作中找到,地址为 https://github.com/laravel/framework/issues/3979

    TestCase.php:

    public function assertHTTPExceptionStatus($expectedStatusCode, Closure $codeThatShouldThrow)
    {
        try 
        {
            $codeThatShouldThrow($this);
    
            $this->assertFalse(true, "An HttpException should have been thrown by the provided Closure.");
        } 
        catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) 
        {
            // assertResponseStatus() won't work because the response object is null
            $this->assertEquals(
                $expectedStatusCode,
                $e->getStatusCode(),
                sprintf("Expected an HTTP status of %d but got %d.", $expectedStatusCode, $e->getStatusCode())
            );
        }
    }
    

    用法:

    public function testGetFailsWith403()
    {
        $this->assertHTTPExceptionStatus(403, function ($_this)
        {
            $_this->call('GET', '/thing-that-should-fail');
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 2021-05-05
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多