有人知道是否有断言或类似的东西可以测试被测试的代码中是否抛出了异常吗?


当前回答

<?php
require_once 'PHPUnit/Framework.php';

class ExceptionTest extends PHPUnit_Framework_TestCase
{
    public function testException()
    {
        $this->expectException(InvalidArgumentException::class);
        // or for PHPUnit < 5.2
        // $this->setExpectedException(InvalidArgumentException::class);

        //...and then add your test code that generates the exception 
        exampleMethod($anInvalidArgument);
    }
}

PHPUnit文档

PHPUnit作者文章提供了关于测试异常最佳实践的详细解释。

其他回答

PhpUnit是一个很棒的库,但这一点有点令人沮丧。这就是为什么我们可以使用turbotesting-php开源库,它有一个非常方便的断言方法来帮助我们测试异常。在这里可以找到:

https://github.com/edertone/TurboTesting/blob/master/TurboTesting-Php/src/main/php/utils/AssertUtils.php

要使用它,我们只需执行以下操作:

AssertUtils::throwsException(function(){

    // Some code that must throw an exception here

}, '/expected error message/');

如果我们在匿名函数中键入的代码没有抛出异常,则会抛出异常。

如果我们在匿名函数中键入的代码抛出异常,但其消息与预期的regexp不匹配,则也将抛出异常。

<?php
require_once 'PHPUnit/Framework.php';

class ExceptionTest extends PHPUnit_Framework_TestCase
{
    public function testException()
    {
        $this->expectException(InvalidArgumentException::class);
        // or for PHPUnit < 5.2
        // $this->setExpectedException(InvalidArgumentException::class);

        //...and then add your test code that generates the exception 
        exampleMethod($anInvalidArgument);
    }
}

PHPUnit文档

PHPUnit作者文章提供了关于测试异常最佳实践的详细解释。

/**
 * @expectedException Exception
 * @expectedExceptionMessage Amount has to be bigger then 0!
 */
public function testDepositNegative()
{
    $this->account->deposit(-7);
}

注意“/**”,注意两个“*”。只写“**”(星号)将使代码失败。 同时确保你使用的是phpUnit的最新版本。在phpunit的一些早期版本中,不支持@expectedException异常。我有4.0,它不适合我,我必须更新到5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composer更新与作曲家。

下面的代码将测试异常消息和异常代码。

重要提示:如果没有抛出预期的异常,它将失败。

try{
    $test->methodWhichWillThrowException();//if this method not throw exception it must be fail too.
    $this->fail("Expected exception 1162011 not thrown");
}catch(MySpecificException $e){ //Not catching a generic Exception or the fail function is also catched
    $this->assertEquals(1162011, $e->getCode());
    $this->assertEquals("Exception Message", $e->getMessage());
}

你也可以在PHPUnit 9发布之前使用文档块注释:

class ExceptionTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     */
    public function testException()
    {
        ...
    }
}

对于PHP 5.5+(特别是带有命名空间的代码),我现在更喜欢使用::class