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\MyException'); $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'); }); }