【发布时间】:2015-02-15 04:12:12
【问题描述】:
我正在尝试测试我编写的以下类中的方法(函数比显示的要多,基本上,每个 is_*() 方法都有一个函数):
class Validate {
private static $initialized = false;
/**
* Construct won't be called inside this class and is uncallable from the outside. This prevents
* instantiating this class. This is by purpose, because we want a static class.
*/
private function __construct() {}
/**
* If needed, allows the class to initialize itself
*/
private static function initialize()
{
if(self::$initialized) {
return;
} else {
self::$initialized = true;
//Set any other class static variables here
}
}
...
public static function isString($string) {
self::initialize();
if(!is_string($string)) throw new InvalidArgumentException('Expected a string but found ' . gettype($string));
}
...
}
当我测试方法是否在无效输入上引发异常时,效果很好!但是,当我测试该方法是否按预期工作时,PHPUnit 会抱怨,因为我在测试中没有断言。具体错误是:
# RISKY This test did not perform any assertions
但是,我没有任何价值可以断言,所以我不确定如何克服这个问题。
我读过一些关于测试静态方法的文章,但这似乎主要涵盖了静态方法之间的依赖关系。此外,即使是非静态方法也可能没有返回值,那么,如何解决这个问题?
供参考,我的测试代码:
class ValidateTest extends PHPUnit_Framework_TestCase {
/**
* @covers ../data/objects/Validate::isString
* @expectedException InvalidArgumentException
*/
public function testIsStringThrowsExceptionArgumentInvalid() {
Validate::isString(NULL);
}
/**
* @covers ../data/objects/Validate::isString
*/
public function testIsStringNoExceptionArgumentValid() {
Validate::isString("I am a string.");
}
}
【问题讨论】:
-
为什么该方法不会返回真/假?为什么将非字符串值作为参数传递时会是一个例外,因为显然是一种测试某物是否为字符串的方法,应该期望非字符串值或者该方法没有实用程序。这似乎是一种考虑不周的方法。
-
@MikeBrant 它不会返回,因为它没有必要。我在我的代码中使用该方法作为中断/断言 - 如果该方法没有引发异常,我的代码将继续正常运行。如果是,则必须处理异常。根本没有理由从这些方法中返回任何内容,更没有理由编写 if/else 语句并花费周期检查这些返回值。我想要异常而不是 TRUE/FALSE,因为异常可以停止代码执行。如果在 Java(或大多数类型化的语言)中将一个 int 放在数组应该放在的位置,则会出现异常。我想要类似的功能。
-
@MikeBrant 此外,正确的测试意味着确保我的方法适用于无效和有效输入。
-
是的,但是当你有这样的验证方法时,为什么验证类要向调用者规定行为呢?也许调用这个类的代码正试图根据值是否为字符串来决定要做的事情,完全期望有时可能存在其他数据类型。为什么这个验证类应该抛出一个必须处理的异常,而不是仅仅给调用者它正在寻找的东西——了解所讨论的值是否确实是字符串类型?这似乎也是一个微不足道的函数,因为 PHP 有这个内置函数。
-
@MikeBrant PHP 确实构建了它,
is_string(),我在函数中使用它。但是,由于我确实使用异常,我不想到处为新的异常编写代码。拥有一个验证类并不少见。我理解你所说的课程是如何运作的,你有正确的观点。然而,你指出的方式不是我设计的方式,虽然我的设计总体上可能并不完美,但我认为它应该是我正在做的事情的方式。
标签: php unit-testing phpunit