有人知道是否有断言或类似的东西可以测试被测试的代码中是否抛出了异常吗?
当前回答
另一种方法是:
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected Exception Message');
请确保您的测试类扩展\PHPUnit_Framework_TestCase。
其他回答
全面的解决方案
PHPUnit当前异常测试的“最佳实践”似乎…低迷(文档)。
由于我想要的不仅仅是当前的expectException实现,所以我在测试用例中使用了一个trait。它只有大约50行代码。
每个测试支持多个异常 支持异常抛出后调用的断言 健壮和清晰的使用示例 标准断言语法 不仅支持消息、代码和类的断言 支持反向断言,assertNotThrows 支持PHP 7可抛出错误
图书馆
我发布了AssertThrows trait到Github和packagist,这样它就可以与composer一起安装了。
简单的例子
只是为了说明语法背后的精神:
<?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();
});
}
}
?>
您可以使用assertException扩展在一次测试执行期间断言多个异常。
插入方法到您的TestCase并使用:
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}
我还为喜欢漂亮代码的人做了一个trait ..
你也可以在PHPUnit 9发布之前使用文档块注释:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
...
}
}
对于PHP 5.5+(特别是带有命名空间的代码),我现在更喜欢使用::class
以下是您可以执行的所有异常断言。注意,它们都是可选的。
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!');
}
}
文档可以在这里找到。
如果你在PHP 5.5+上运行,你可以使用::class解析通过expectException/setExpectedException获取类名。这有几个好处:
名称将完全限定其名称空间(如果有的话)。 它将解析为一个字符串,因此它将适用于任何版本的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
into
"\My\Cool\Package\WrongPasswordException"
没有PHPUnit是明智的。
注意:PHPUnit 5.2引入了expectException作为setExpectedException的替换。
推荐文章
- 原则-如何打印出真正的sql,而不仅仅是准备好的语句?
- 如何从关联PHP数组中获得第一项?
- PHP/MySQL插入一行然后获取id
- 我如何排序一个多维数组在PHP
- 如何在PHP中截断字符串最接近于一定数量的字符?
- PHP错误:“zip扩展名和unzip命令都没有,跳过。”
- Nginx提供下载。php文件,而不是执行它们
- Json_encode()转义正斜杠
- 如何在PHP中捕获cURL错误
- 如何要求一个分叉与作曲家?
- 'throw'和'throw new Exception()'的区别
- 如何在php中创建可选参数?
- 在文本文件中创建或写入/追加
- 为什么PHP的json_encode函数转换UTF-8字符串为十六进制实体?
- 导致java.lang.VerifyError错误的原因