【问题标题】:PHPUnit not asserting ExceptionsPHPUnit没有断言异常
【发布时间】:2016-03-15 13:57:31
【问题描述】:

我正在使用 phpunit 4.8.23 和 laravel 5.2。

我的一个控制器正在抛出一个 HttpException,如下所示。

throw new HttpException(403, 'auth_failure');

在 Handler.php 中

if ($e instanceof HttpException){
    return response()->json(array(...), $e->getStatusCode());
}

为了对此进行测试,我在测试文件中使用了以下代码。

1

/**
 * @expectedException Symfony\Component\HttpKernel\Exception\HttpException
 * @expectedExceptionMessage auth_failure
 */
  public function testMethod(){....}

2

public function testMethod(){
$this->json(.....);
$this->setExpectedException('HttpException');
}

3 甚至尝试 catch

try {$this->json(....)}
catch(\Symfony\Component\HttpKernel\Exception\HttpException $e){..}

我也用\Exception 尝试了第三种情况。

在所有情况下,我都会得到输出

PHPUnit 4.8.23 by Sebastian Bergmann and contributors.

.Symfony\Component\HttpKernel\Exception\HttpException {#986
-statusCode: 403
-headers: []
#message: "auth_failure"
#code: 0
#file: "<path to file>"
#line: 103
-trace: {
57. App\Http\Controllers\DeviceController->register() ==> new    Symfony\Component\HttpKernel\Exception\HttpException(): {.....

我已经解决了thisthisthis 的问题,但没有取得任何进展。

编辑 我希望我已经提供了所有相关信息。无论如何,这是完整的方法

/**
 * @expectedException Symfony\Component\HttpKernel\Exception\HttpException
 * @expectedExceptionMessage auth_failure
 */
public function testRegAuthFailure()
{

    $this->json('POST',
                'auth',
                [
                    "lang" => "us_en",
                    "data" => [
                        "identity"      => "00000004",
                        "password"      => "wrong",              
                    ]
                ]
    );

    $this->setExpectedException('HttpException');
}

感谢任何帮助:)

【问题讨论】:

  • 能否请您发布您尝试运行的实际代码(即您的测试的完整代码testMethod)?
  • 这里是实际代码
  • 你试过直接在“testRegAuthFailure”里面抛出异常吗?
  • 那行得通,即thow new HttpException(403, 'auth_failure');而不是json方法调用。

标签: php unit-testing phpunit laravel-5.2


【解决方案1】:

我认为您将单元测试与功能测试混为一谈。当您运行功能测试时,您需要测试实际输出,例如标题和 html/json/如果您向您的“/user”API 方法发出 POST 请求,您将在浏览器中看到的任何内容。

对于 puse 单元测试,您需要创建 Controller 并直接运行它的方法,例如

class ControllerTest extends PHPUnit_Framework_TestCase {

    /**
     * @expectedException Symfony\Component\HttpKernel\Exception\HttpException
     * @expectedExceptionMessage auth_failure
     */
    public function testSomeMethod() {
        $controller = new Controller(/* mocked dependencies */);
        $controller->yourMethod();
    }

}

另一方面,对于功能测试,我更喜欢测试实际响应(HTTP 代码和内容)。您还可以在 Handler.php 中捕获 HttpException,因此您不能期望在测试中出现任何异常。您返回响应 - 它在您的测试中变为 $this-&gt;response

这对我有用:

// Handler.php
if ($e instanceof HttpException) {
    return response()->json(array($e->getMessage()), $e->getStatusCode());
}


// Test
public function testRegAuthException()
{
    $this->json('POST',
        'auth',
        [
            "lang" => "us_en",
            "data" => [
                "identity"      => "00000004",
                "password"      => "wrong",
            ]
        ]
    )->seeJson(["auth_failure"]);
    $this->assertEquals($this->response->getStatusCode(), 403);
    // OR
    // $this->assertResponseStatus(403);
}

附:如果你想期待一些异常 - 不要在 Handler.php 中捕获它,它将通过$result-&gt;response-&gt;exception 进行测试

如果我错了,请纠正我:) 并有一个很好的编码!

【讨论】:

  • 这是一个laravel提供的测试框架,不好意思之前没提过。 Laravel Testing
  • 是的,我知道,并且它是为功能测试而创建的,所以期望控制器的异常不是应该如何完成的。无论如何,它建立在 PHPUnit 之上,所以 phpunit 的 API 是可用的
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 2018-08-21
  • 1970-01-01
  • 2011-01-26
  • 2011-03-29
  • 2018-01-03
  • 2013-09-15
  • 2013-05-02
相关资源
最近更新 更多