有誰知道是否有assert
或類似的東西,可以測試是否在被測試的代碼中拋出異常?PHPUnit斷言引發了異常?
回答
<?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 documentation
PHPUnit author article提供測試異常的最佳做法的詳細說明。
+1不依賴魔術文檔塊 – SuperFamousGuy 2014-04-22 19:29:20
如果您使用命名空間,那麼您需要輸入完整的命名空間:'$ this-> setExpectedException('\ My \ Name \ Space \ MyCustomException');' – Alcalyn 2014-11-25 15:50:09
請注意,似乎沒有一種明確期望沒有例外的方法。您只需調用您的方法,如果拋出異常,測試將自動失敗。 – 2015-06-23 14:53:11
你也可以使用一個docblock annotation:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
...
}
}
對於PHP 5.5+(特別是與命名空間中的代碼),我現在更喜歡用下面::class
IMO,這是首選的方法。 – 2012-06-15 20:16:38
@MikePurcell,爲什麼? – 2013-05-23 07:04:00
@Falken教授:個人喜好。 Docblock註釋保持測試方法的清潔,並且幾個框架正在使用相同的做法; symfony 2,zf2。 – 2013-05-23 17:35:23
代碼將測試異常消息和異常代碼。
重要提示:如果預期的異常沒有被拋出,它將會失敗。
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());
}
'$ this-> fail()'並不意味着以這種方式使用,我不認爲,至少目前不是(PHPUnit 3.6.11);它本身就是一種例外。使用你的例子,如果'$ this-> fail(「Expected exception not thrown」)被調用,那麼'catch'模塊被觸發並且'$ e-> getMessage()'是_「期望的異常不被拋出_ 。 – ken 2014-04-16 21:33:51
@ken你可能是對的。對'失敗'的調用可能屬於* catch塊之後,而不是在try中。 – 2014-04-22 20:41:57
我必須downvote,因爲'fail'的調用不應該在'try'塊中。它本身觸發了「catch」塊產生虛假結果。 – Twifty 2015-04-09 21:53:00
您可以使用assertException extension在一次測試執行期間聲明多個異常。
方法插入到你的測試用例和使用:
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException($test, 'InvalidArgumentException', 100, 'expected message');
}
我還做了好看的代碼愛好者trait ...
您正在使用哪個PHPUnit?我正在使用PHPUnit 4.7.5,並且沒有定義'assertException'。我也無法在PHPUnit手冊中找到它。 – physicalattraction 2015-07-22 08:34:46
'asertException'方法不是原始PHPUnit的一部分。您必須手動繼承'PHPUnit_Framework_TestCase'類並添加[在上面的帖子中鏈接的方法](https://gist.github.com/VladaHejda/8826707)。你的測試用例會繼承這個繼承的類。 – hejdav 2015-07-27 11:40:03
public function testException() {
try {
$this->methodThatThrowsException();
$this->fail("Expected Exception has not been raised.");
} catch (Exception $ex) {
$this->assertEquals($ex->getMessage(), "Exception message");
}
}
如果你在運行PHP 5.5+,您可以使用::class
resolution來獲取expectException
/setExpectedException
的課程名稱。這提供了幾個好處:
- 該名稱將完全限定其名稱空間(如果有)。
- 它解析爲
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 introduced
expectException
作爲setExpectedException
的替代品。
/**
* @expectedException Exception
* @expectedExceptionMessage Amount has to be bigger then 0!
*/
public function testDepositNegative()
{
$this->account->deposit(-7);
}
要非常小心約"/**"
,注意雙 「*」。只寫「* *」(asterix)會使你的代碼失敗。 也請確保您使用的是phpUnit的最新版本。在phpunit的一些早期版本中,@expectedException異常不受支持。我有4.0,它不適合我,我不得不更新到5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composer與作曲家更新。
的另一種方式可以是follwing:
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Expected Exception Message');
請確保您的測試類範圍\化PHPUnit_Framework_TestCase
這裏的所有異常的斷言,你可以做。請注意,它們全部是可選。
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!');
}
}
可以找到文檔here。
PHPUnit expectException
方法非常不方便,因爲它允許每個測試方法只測試一個異常。
我做了這個輔助函數來斷言某些函數拋出一個異常:
/**
* 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');
}
這種方式添加到您的測試類,並呼籲:
public function testSomething() {
$this->assertException(\PDOException::class, function() {
new \PDO('bad:param');
});
$this->assertException(\PDOException::class, function() {
new \PDO('foo:bar');
});
}
- 1. 強制asp.net斷言引發異常?
- 2. 使用unittest斷言引發的異常
- 3. 如何斷言沒有引發異常?
- 4. 爲什麼PHPUnit在期待異常時會忽略斷言?
- 5. 異常發生後評估斷言?
- 6. 如何斷言函數不會引發異常
- 7. C++斷言函數檢查引發異常
- 8. MongoDB Map/Reduce引發異常:失敗:db斷言失敗
- 9. Magento phpunit斷言 - assertEquals(true,false)
- 10. PHPUnit異常
- 11. 'System.Windows.Setter'的初始化引發了異常
- 12. 的libC++ abi.dylib:terminate_handler意外引發了異常
- 13. 使用ObjectContext的後引發了異常
- 14. 引發了類型'System.OutOfMemoryException'的異常。
- 15. 引發異常
- 16. 引發異常
- 17. 引發異常
- 18. 引發異常
- 19. );引發異常
- 20. 異常斷言連同其他斷言jUnit
- 21. PHPUnit模擬異常
- 22. PHPUnit的測試的ExpectedException不會引發異常
- 23. PHPUnit的引發異常時,不會找到測試套件
- 24. 調用的目標引發了異常。引發UserPrincipal
- 25. JBehave:不要把斷言異常
- 26. FakeItEasy - 捕獲異常斷言消息
- 27. 如何使用Jasmine斷言異常?
- 28. 如何斷言與Bddfy異常
- 29. Java,WebDriver,斷言/異常和UI狀態
- 30. 斷言處理的異常被拋出
爲這些問題的答案:什麼測試函數中的多重斷言,我只希望有一個拋出異常?我是否需要將它們分開並將其置於獨立的測試功能中? – 2016-01-22 08:04:53