PHPUnit如何断言是否抛出了异常?

467

请问是否有一种assert或类似的东西可以测试正在测试的代码中是否抛出了异常?


3
针对这些回答:如果一个测试函数中有多个断言,我只期望其中一个抛出异常,我是否必须将其分开并放入独立的测试函数中? - Panwen Wang
2
@PanwenWang 要测试多个异常或从异常的getter函数中返回多个值,请参见此答案 - Jimmix
15个回答

7

以下是所有异常断言,需要注意的是它们都是可选的。

class ExceptionTest extends PHPUnit_Framework_TestCase
{
    public function testException()
    {
        // make your exception assertions
        $this->expectException(InvalidArgumentException::class);
        // if you use namespaces:
        // $this->expectException('\Namespace\MyExceptio‌​n');
        $this->expectExceptionMessage('message');
        $this->expectExceptionMessageRegExp('/essage$/');
        $this->expectExceptionCode(123);
        // code that throws an exception
        throw new InvalidArgumentException('message', 123);
   }

   public function testAnotherException()
   {
        // repeat as needed
        $this->expectException(Exception::class);
        throw new Exception('Oh no!');
    }
}

文档可以在这里找到。


1
这是不正确的,因为PHP会在第一个抛出的异常处停止。PHPUnit检查抛出的异常是否具有正确的类型,并说“测试通过”,它甚至不知道第二个异常的存在。 - Finesse

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

非常小心的是"/**",注意双星号。只写一个星号*将使你的代码失败。
同时确保你使用的是最新版本的phpUnit。在一些早期版本的phpunit中,@expectedException Exception不被支持。我用的是4.0版本没能成功,必须更新到5.5。https://coderwall.com/p/mklvdw/install-phpunit-with-composer 可以通过composer更新。

1

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/');

如果我们在匿名函数内输入的代码没有抛出异常,就会抛出异常。
如果我们在匿名函数内输入的代码抛出了异常,但其消息不匹配预期的正则表达式,也将抛出异常。

0
对于PHPUnit 5.7.27和PHP 5.6,为了在一个测试中测试多个异常,强制进行异常测试非常重要。仅使用异常处理来断言Exception的实例将跳过测试情况,如果没有发生异常。
public function testSomeFunction() {

    $e=null;
    $targetClassObj= new TargetClass();
    try {
        $targetClassObj->doSomething();
    } catch ( \Exception $e ) {
    }
    $this->assertInstanceOf(\Exception::class,$e);
    $this->assertEquals('Some message',$e->getMessage());

    $e=null;
    try {
        $targetClassObj->doSomethingElse();
    } catch ( Exception $e ) {
    }
    $this->assertInstanceOf(\Exception::class,$e);
    $this->assertEquals('Another message',$e->getMessage());

}

0
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 

   }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接