有人知道是否有断言或类似的东西可以测试被测试的代码中是否抛出了异常吗?
当前回答
PHPUnit expectException方法非常不方便,因为它只允许每个测试方法测试一个异常。
我使用这个helper函数来断言某个函数抛出异常:
/**
* 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');
});
}
其他回答
你也可以在PHPUnit 9发布之前使用文档块注释:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
...
}
}
对于PHP 5.5+(特别是带有命名空间的代码),我现在更喜欢使用::class
PHPUnit expectException方法非常不方便,因为它只允许每个测试方法测试一个异常。
我使用这个helper函数来断言某个函数抛出异常:
/**
* 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');
});
}
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
}
}
您可以使用assertException扩展在一次测试执行期间断言多个异常。
插入方法到您的TestCase并使用:
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}
我还为喜欢漂亮代码的人做了一个trait ..
如果你在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的替换。
推荐文章
- 致命错误:未找到类“SoapClient”
- django MultiValueDictKeyError错误,我如何处理它
- 我目前使用的是哪个版本的CodeIgniter ?
- 合并两个PHP对象的最佳方法是什么?
- 如何使HTTP请求在PHP和不等待响应
- 发送附件与PHP邮件()?
- 如何获得当前的路线在Symfony 2?
- 为什么这个迭代的列表增长代码给出IndexError:列表赋值索引超出范围?如何重复添加(追加)元素到列表?
- 用PHP删除字符串的前4个字符
- mysql_connect():[2002]没有这样的文件或目录(试图通过unix:///tmp/mysql.sock连接)在
- 一个函数的多个返回值
- 我怎么能得到抛出异常的行号?
- 在PHP中使用foreach循环时查找数组的最后一个元素
- 检查数组是否为空
- PHP DOMDocument loadHTML没有正确编码UTF-8