如何通过self::
测试具有附带效果的类的方法?如:
final class Foo{
private static $effect = false;
public static function doit( $arg ){
if( self::effect ) return;
self::check_args( $arg );
self::$effect = true;
}
private function check_args($arg){
#validate and trhow exception if invalid
}
}
我必须向doit()发送几个args来测试它正确验证值,但是在第一次运行之后它只是绕过它。它基本上是一个单例的初始化方法,它设置了一个初始化标志。
我还不能真正把课程搞得一团糟。有没有什么方法可以用self::
的方式对对象进行复制/实例化?
答案 0 :(得分:2)
该课程应改写为:
class Foo{
private $effect = false;
public function doit( $arg ){
if( $this->effect ) return;
$this->check_args( $arg );
$this->effect = true;
}
private function check_args($arg){
#validate and trhow exception if invalid
}
}
self::
仅用于static
函数和变量,在大多数情况下,您应避免使用这些函数和变量。
答案 1 :(得分:1)
如何在测试环境中添加被测试类的子类,然后使用它来操作静态变量。在下面的示例中,我稍微修改了您的代码,因此$ effect的值更容易使用,而且我还必须将$效果的范围提升到受保护的范围:
<?php
class Foo{
protected static $effect = "0";
public static function doit( $arg ) {
echo 'I got: ' . $arg . ' and effect is: ' . self::$effect . '<br>';
self::$effect = "1";
}
}
class FooChild extends Foo {
public static function setEffect($newEffect) {
self::$effect = $newEffect;
}
}
Foo::doit('hello');
Foo::doit('world');
FooChild::setEffect('3');
Foo::doit('three');
输出是这样的:
我得到了:你好,效果是:0(第一次显示初始值)
我得到了:世界和效果是:1(第二次通过显示在doit中由Foo递增的值()
我得到:三,效果是:3(第三次通过,表明子类能够改变父级的值)