在PHP中使用self ::的unittest类

时间:2012-03-20 22:21:58

标签: php unit-testing testing phpunit

如何通过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::的方式对对象进行复制/实例化?

2 个答案:

答案 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(第三次通过,表明子类能够改变父级的值)