PHPUnit 抽象类常量

3

我正在尝试找到一种测试抽象类常量的方法,该常量必须存在并匹配/不匹配一个值。例如:

// to be extended by ExternalSDKClild
abstract class ExternalSDK {
    const VERSION = '3.1.1.'; 
}


class foo extends AController {
    public function init() {   
        if ( ExternalSDK::VERSION !== '3.1.1' ) {
            throw new Exception('Wrong ExternalSDK version!');
        }

        $this->setExternalSDKChild(new ExternalSDKChild());
    }
}

限制... 我们使用的框架不允许在init()方法中进行依赖注入。(重构init()方法可能是解决问题的方法...)

我运行的单元测试和代码覆盖率已经覆盖了所有内容,除了异常。我无法想出一种使ExternalSDK::Version与其不同的方法。

欢迎各种想法。

1个回答

1

首先,将对new的调用重构为单独的方法。

其次,添加一个获取版本的方法,而不是直接访问常量。在PHP中,类常量在解析时编译到文件中,不能更改。*由于它们是静态访问的,没有办法在不使用具有相同名称的不同类声明替换的情况下覆盖它。使用标准PHP唯一的方法是在单独的进程中运行测试,这非常昂贵。

class ExternalSDK {
    const VERSION = '3.1.1';

    public function getVersion() {
        return static::VERSION;
    }
}

class foo extends AController {
    public function init() {
        $sdk = $this->createSDK();
        if ( $sdk->getVersion() !== '3.1.1' ) {
            throw new Exception('Wrong ExternalSDK version!');
        }

        $this->setExternalSDKChild($sdk);
    }

    public function createSDK() {
        return new ExternalSDKChild();
    }
}

现在进行单元测试。

class NewerSDK extends ExternalSDK {
    const VERSION = '3.1.2';
}

/**
 * @expectedException Exception
 */
function testInitFailsWhenVersionIsDifferent() {
    $sdk = new NewerSDK();
    $foo = $this->getMock('foo', array('createSDK'));
    $foo->expects($this->once())
        ->method('createSDK')
        ->will($this->returnValue($sdk));
    $foo->init();
}

*Runkit提供了runkit_constant_redefine(),这可能适用于此处。您需要手动捕获异常,而不是使用@expectedException,以便可以将常量重置为正确的值。或者您可以在tearDown()中执行此操作。

function testInitFailsWhenVersionIsDifferent() {
    try {
        runkit_constant_redefine('ExternalSDK::VERSION', '3.1.0');
        $foo = new foo();
        $foo->init();
        $failed = true;
    }
    catch (Exception $e) {
        $failed = false;
    }
    runkit_constant_redefine('ExternalSDK::VERSION', '3.1.1');
    if ($failed) {
        self::fail('Failed to detect incorrect SDK version.');
    }
}

1
在我看来,为一个类常量设置getter完全破坏了常量的目的。 - donatJ
@donatJ - 你可以通过删除常量并直接从getVersion返回值来轻松重构它,但是用较小的更改来演示这种单元测试技术会更容易些。 - David Harkness

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接