Chu*_*uck 8 php unit-testing simpletest
我一直在这里阅读一些关于使用单元测试来测试私有方法和属性的问题.我是单元测试的新手,想要输入我正在尝试的方法,以便我的测试可以访问私有/受保护的属性和方法.
在我正在进行的测试中,我想确认将特定参数传递给对象会导致设置属性.我正在使用SimpleTest进行单元测试教育,我的测试方法如下:
function test__Construction_Should_Properly_Set_Tables() {
$cv = new CVObject( array( 'tables' => $this->standardTableDef ) );
$tables = $cv->tables;
$this->assertEqual( $tables, $this->standardTableDef );
}
Run Code Online (Sandbox Code Playgroud)
然后我在CVObject中写了一个__get方法,如下所示:
function __get( $name ) {
$trace = debug_backtrace();
$caller = $trace[1];
$inTesting = preg_match( '/simpletest/', $caller['file'] );
if ( $inTesting ) {
return $this->$name;
} else {
trigger_error( 'Cannot access protected property CVObject::$' .
$name . ' in ' . $trace[0]['file'] . ' on line ' .
$trace[0]['line'],
E_USER_NOTICE );
}
}
Run Code Online (Sandbox Code Playgroud)
我的想法是,如果调用文件来自SimpleTest,请继续使该属性可用于测试目的,但如果没有,则触发错误.这允许我保持属性私有但能够在测试中使用它,这对我来说更重要的是我将要开始编写的特定私有方法.
所以,我的问题是,我错过了一些非常糟糕的东西,应该避免这种技术吗?
Dav*_*ess 10
如果您发现自己陷入困境并且必须访问私有/受保护的属性以启用全面测试,那么至少应该在您的测试或测试框架中放置支持访问的代码.在生产代码中嵌入仅测试代码a)使设计复杂化,b)添加必须测试的更多代码,c)意味着代码在生产中运行不同.
您可以将Ken的子类方法用于受保护的属性,但如果您需要访问private并且在PHP 5.3.2+上,则可以使用反射.
function test__Construction_Should_Properly_Set_Tables() {
$cv = new CVObject( array( 'tables' => $this->standardTableDef ) );
$tables = self::getPrivate($cv, 'tables');
$this->assertEqual( $tables, $this->standardTableDef );
}
static function getPrivate($object, $property) {
$reflector = new ReflectionProperty(get_class($object), $property);
$reflector->setAccessible(true);
return $reflector->getValue($object);
}
Run Code Online (Sandbox Code Playgroud)
请注意,getPrivate()对于从超类继承的属性所写的不起作用,但是循环层次结构以查找声明类并不太难.