PHPUnit断言是否引发了异常?

| 有谁知道是否有一个“ 0”或类似的东西可以测试被测代码中是否抛出了异常?     
已邀请:
<?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);
    }
}
ExpectException()PHPUnit文档 PHPUnit作者文章提供了有关测试异常最佳实践的详细说明。     
您还可以使用docblock批注:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     */
    public function testException()
    {
        ...
    }
}
对于PHP 5.5+(尤其是带有命名空间的代码),我现在更喜欢使用
::class
    
如果您在PHP 5.5+上运行,则可以使用
::class
解析度来获取带有
expectException
/
setExpectedException
的类的名称。这提供了几个好处: 该名称将带有其名称空间(如果有)完全限定。 它解析为“ 7”,因此可以与任何版本的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
进入
\"\\My\\Cool\\Package\\WrongPasswordException\"
没有PHPUnit是更明智的选择。   注意:PHPUnit 5.2引入了ѭ5来代替
setExpectedException
。     
下面的代码将测试异常消息和异常代码。 重要说明:如果也未引发预期的异常,它将失败。
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());
}
    
您可以使用assertException扩展在一个测试执行期间声明一个以上的异常。 将方法插入TestCase并使用:
public function testSomething()
{
    $test = function() {
        // some code that has to throw an exception
    };
    $this->assertException( $test, \'InvalidArgumentException\', 100, \'expected message\' );
}
我还为喜欢精美代码的爱好者们赋予了一个特质。     
一种替代方法可以是以下方法:
$this->expectException(\\InvalidArgumentException::class);
$this->expectExceptionMessage(\'Expected Exception Message\');
请确保您的测试课程范围为
\\PHPUnit_Framework_TestCase
。     
PHPUnit的“ 5”方法非常不便,因为每个测试方法只能测试一个异常。 我已经使这个辅助函数断言某些函数抛出异常:
/**
 * 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\');
    });
}
    
public function testException() {
    try {
        $this->methodThatThrowsException();
        $this->fail(\"Expected Exception has not been raised.\");
    } catch (Exception $ex) {
        $this->assertEquals($ex->getMessage(), \"Exception message\");
    }

}
    
综合解决方案 PHPUnit \当前用于例外测试的“最佳实践”似乎..缺乏光泽(文档)。 因为我想要的不仅仅是当前的“ 5”实现,所以我在测试用例中使用了一个特质。大约只有50行代码。 支持每个测试多个异常 支持引发异常后调用的断言 稳健而清晰的用法示例 标准
assert
语法 支持断言,而不仅仅是消息,代码和类 支持反断言,
assertNotThrows
支持PHP 7
Throwable
错误 图书馆 我向Github和packagist发布了ѭ25特征,以便可以在作曲家中安装它。 简单的例子 只是为了说明语法背后的精神:
<?php

// Using simple callback
$this->assertThrows(MyException::class, [$obj, \'doSomethingBad\']);

// Using anonymous function
$this->assertThrows(MyException::class, function() use ($obj) {
    $obj->doSomethingBad();
});
挺整洁的? 完整用法示例 请参阅下面的更全面的用法示例:
<?php

declare(strict_types=1);

use Jchook\\AssertThrows\\AssertThrows;
use PHPUnit\\Framework\\TestCase;

// These are just for illustration
use MyNamespace\\MyException;
use MyNamespace\\MyObject;

final class MyTest extends TestCase
{
    use AssertThrows; // <--- adds the assertThrows method

    public function testMyObject()
    {
        $obj = new MyObject();

        // Test a basic exception is thrown
        $this->assertThrows(MyException::class, function() use ($obj) {
            $obj->doSomethingBad();
        });

        // Test custom aspects of a custom extension class
        $this->assertThrows(MyException::class, 
            function() use ($obj) {
                $obj->doSomethingBad();
            },
            function($exception) {
                $this->assertEquals(\'Expected value\', $exception->getCustomThing());
                $this->assertEquals(123, $exception->getCode());
            }
        );

        // Test that a specific exception is NOT thrown
        $this->assertNotThrows(MyException::class, function() use ($obj) {
            $obj->doSomethingGood();
        });
    }
}

?>
    
您可以执行以下所有异常断言。请注意,所有这些都是可选的。
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!\');
    }
}
文档可以在这里找到。     
/**
 * @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才能使用composer进行更新。     
对于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());

}
    
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 

   }

}
    
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/\');
如果我们在匿名函数中键入的代码未引发异常,则将引发异常。 如果我们在匿名函数中键入的代码引发异常,但其消息与预期的正则表达式不匹配,则也会引发异常。     

要回复问题请先登录注册