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


当前回答

PHPUnit expectException方法非常不方便,因为它只允许每个测试方法测试一个异常。

我使用这个helper函数来断言某个函数抛出异常:

/**
 * Asserts that the given callback throws the given exception.
 *
 * @param string $expectClass The name of the expected exception class
 * @param callable $callback A callback which should throw the exception
 */
protected function assertException(string $expectClass, callable $callback)
{
    try {
        $callback();
    } catch (\Throwable $exception) {
        $this->assertInstanceOf($expectClass, $exception, 'An invalid exception was thrown');
        return;
    }

    $this->fail('No exception was thrown');
}

将它添加到您的测试类中,并以这样的方式调用:

public function testSomething() {
    $this->assertException(\PDOException::class, function() {
        new \PDO('bad:param');
    });
    $this->assertException(\PDOException::class, function() {
        new \PDO('foo:bar');
    });
}

其他回答

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

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

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

PHPUnit expectException方法非常不方便,因为它只允许每个测试方法测试一个异常。

我使用这个helper函数来断言某个函数抛出异常:

/**
 * Asserts that the given callback throws the given exception.
 *
 * @param string $expectClass The name of the expected exception class
 * @param callable $callback A callback which should throw the exception
 */
protected function assertException(string $expectClass, callable $callback)
{
    try {
        $callback();
    } catch (\Throwable $exception) {
        $this->assertInstanceOf($expectClass, $exception, 'An invalid exception was thrown');
        return;
    }

    $this->fail('No exception was thrown');
}

将它添加到您的测试类中,并以这样的方式调用:

public function testSomething() {
    $this->assertException(\PDOException::class, function() {
        new \PDO('bad:param');
    });
    $this->assertException(\PDOException::class, function() {
        new \PDO('foo:bar');
    });
}
function yourfunction($a,$z){
   if($a<$z){ throw new <YOUR_EXCEPTION>; }
}

下面是测试

class FunctionTest extends \PHPUnit_Framework_TestCase{

   public function testException(){

      $this->setExpectedException(<YOUR_EXCEPTION>::class);
      yourfunction(1,2);//add vars that cause the exception 

   }

}

您可以使用assertException扩展在一次测试执行期间断言多个异常。

插入方法到您的TestCase并使用:

public function testSomething()
{
    $test = function() {
        // some code that has to throw an exception
    };
    $this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}

我还为喜欢漂亮代码的人做了一个trait ..

如果你在PHP 5.5+上运行,你可以使用::class解析通过expectException/setExpectedException获取类名。这有几个好处:

名称将完全限定其名称空间(如果有的话)。 它将解析为一个字符串,因此它将适用于任何版本的PHPUnit。 在IDE中实现代码完成。 如果键入错误的类名,PHP编译器将发出一个错误。

例子:

namespace \My\Cool\Package;

class AuthTest extends \PHPUnit_Framework_TestCase
{
    public function testLoginFailsForWrongPassword()
    {
        $this->expectException(WrongPasswordException::class);
        Auth::login('Bob', 'wrong');
    }
}

PHP编译

WrongPasswordException::class

into

"\My\Cool\Package\WrongPasswordException"

没有PHPUnit是明智的。

注意:PHPUnit 5.2引入了expectException作为setExpectedException的替换。