Dan*_*nie 12 php methods phpunit protected abstract
使用PHPUnit和PHP> = 5.3,可以测试受保护的方法.stackoverflow的以下页面概述了它的最佳实践:
protected static function callProtectedMethod($name, $classname, $params) {
$class = new ReflectionClass($classname);
$method = $class->getMethod($name);
$method->setAccessible(true);
$obj = new $classname($params);
return $method->invokeArgs($obj, $params);
}
Run Code Online (Sandbox Code Playgroud)
使用PHPUnit可以轻松地在抽象类上测试公共方法.使用上述方法可以轻松地测试正常类上的受保护方法.要测试抽象类上的受保护方法必须以某种方式...
我知道PHPUnit派生抽象类并在具体类中"实现"抽象方法并针对该具体类触发测试 - 但我不知道如何将其集成到上面的方法中以获得callProtectedMethodOnAbstractClasses().
你是怎么做这样的测试的?
PS:问题不在于测试受保护方法的真相(参见:白色,灰色和黑盒测试).测试受保护方法的需要取决于您的测试策略.
edo*_*ian 24
既然您要求"最佳实践",我将采取不同的方法来回答:
只是因为你不能意味着你应该这样做.
您想测试一个类是否有效.这意味着你可以调用它的所有函数(一切都是公共的)返回正确的值(并且可能在传入的对象上调用正确的函数)而不是其他任何函数.
你不关心这是如何在课堂上实现的.
Imho甚至伤害你为非公开的任何东西写测试有两个重要原因:
编写测试需要更长时间,因为您需要更多,重构也需要更长时间.如果您在类中移动代码而不更改其行为,则不需要更新其测试.测试应告诉你一切仍然有效!
如果您为每个受保护的方法编写测试,则会从代码覆盖率报告中遗漏一个继承的好处:它不会告诉您哪些受保护的函数不再被调用.这是(恕我直言)一件坏事,因为你要么不正确测试所有的公共方法(为什么有一个,如果你测试每一个案件未调用的方法?),或者你真的不需要这种方法了,但由于这是"绿色",你不再考虑它.
所以:仅仅因为对受保护和私有属性和方法的测试是可能的并不意味着这是一件"好事".
http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
...->setAccessible() 适用于普通方法
用于抽象的东西 ...->getMockForAbstractClass()
但是,只有在真的有必要时才这样做.
抽象类中的受保护方法将通过使用上面的应用参数测试其子项的公共api来进行测试.
假设:您希望在抽象类上调用具体的受保护方法.
为抽象类创建一个模拟对象,并将其传递给此修改后的形式callProtectedMethod().
public static function callProtectedMethod($object, $method, array $args=array()) {
$class = new ReflectionClass(get_class($object));
$method = $class->getMethod($method);
$method->setAccessible(true);
return $method->invokeArgs($object, $args);
}
public function testGetArea() {
$rect = $this->getMockForAbstractClass('RandomRectangle');
self::callProtectedMethod($rect, 'setWidth', array(7));
self::callProtectedMethod($rect, 'setHeight', array(3));
self::assertEquals(21, $rect->getArea());
}
Run Code Online (Sandbox Code Playgroud)
您可以将其封装到单个方法中,但我更喜欢传入对象,以便测试可以在同一个对象上调用多个受保护/私有方法.为此,请使用$class->isAbstract()以决定如何构造对象.
| 归档时间: |
|
| 查看次数: |
12431 次 |
| 最近记录: |