phpunit 抽象类常量

发布于 2024-12-10 17:13:32 字数 596 浏览 0 评论 0原文

我正在尝试找到一种方法来测试必须存在且匹配/不匹配值的抽象类常量。示例:

// 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 与它的实际情况不同。

欢迎所有想法

I'm trying to find a way to test a abstract class constant that must exist and match/not match a value. Example:

// 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());
    }
}

Limitations... The framework we use doesn't allow dependency injection in the init() method. (Suggestion to refactor the init() method could be the way to go...)

The unit tests and code coverage I have run, cover all but the Exception. I can't figure out a way to make the ExternalSDK::Version to be different from what it is.

All thoughts welcome

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

原谅过去的我 2024-12-17 17:13:32

首先,将对 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.');
    }
}

First, refactor the call to new into a separate method.

Second, add a method to acquire the version instead of accessing the constant directly. Class constants in PHP are compiled into the file when parsed and cannot be changed.* Since they are accessed statically, there's no way to override it without swapping in a different class declaration with the same name. The only way to do that using standard PHP is to run the test in a separate process which is very expensive.

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();
    }
}

And now for the unit test.

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 provides runkit_constant_redefine() which may work here. You'll need to catch the exception manually instead of using @expectedException so you can reset the constant back to the correct value. Or you can do it in 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.');
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文