PHPUnit断言抛出exception?

有没有人知道是否有一个assert或类似的东西,可以testing是否在被testing的代码中抛出exception?

 <?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的作者文章提供了关于testingexception最佳实践的详细解释。

您也可以使用docblock注释 :

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

对于PHP 5.5+(尤其是命名空间代码),我现在更喜欢使用::class

如果你运行在PHP 5.5+上,你可以使用::class resolution来获得带有expectException / setExpectedException的类的名字。 这提供了几个好处:

  • 该名称将完全限定其名称空间(如果有的话)。
  • 它parsing为一个string因此它可以与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引入了 expectException作为expectException的替代。

下面的代码将testingexception消息和exception代码。

重要提示:如果预期的exception不会抛出,则会失败。

 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扩展在一次testing执行期间声明多个exception。

将方法插入到TestCase中并使用:

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

我也做了一个好代码爱好者的特质 ..

 public function testException() { try { $this->methodThatThrowsException(); $this->fail("Expected Exception has not been raised."); } catch (Exception $ex) { $this->assertEquals($ex->getMessage(), "Exception message"); } } 

另一种方式可以是以下的方式:

 $this->expectException(\Exception::class); $this->expectExceptionMessage('Expected Exception Message'); 

请确保您的testing类扩展\ PHPUnit_Framework_TestCase

以下是您可以执行的所有exception声明。 请注意,所有这些都是可选的

 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!'); } } 

文档可以在这里find。

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

"/**"要小心,注意双“*”。 只写“**”(asterix)会使你的代码失败。 还要确保你使用的是phpUnit的最新版本。 在phpunit的某些早期版本中,@expectedExceptionexception不受支持。 我有4.0,它不适合我,我不得不更新到5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composer更新与composer php。

PHPUnit的expectException方法非常不方便,因为它允许每个testing方法只testing一个exception。

我做了这个帮助函数来声明某个函数抛出一个exception:

 /** * 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); return; } $this->fail('No exception was thrown'); } 

把它添加到你的testing类中,然后调用这个方法:

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