【问题标题】:Using constants across namespaces跨命名空间使用常量
【发布时间】:2011-12-08 23:11:41
【问题描述】:

我在我的框架项目中使用命名空间和 PHP 5.3。我有主要的App 类和一个Autoloader 类。在App类中,我设置了几个环境变量:

public static function setupEnv()
        {
            $os = 'UNIX';
            if (stristr(PHP_OS,'WIN'))
            {
                $os = 'WIN';
            }

            if (!defined('DIRECTORY_SEPARATOR'))
            {
                define('DIRECTORY_SEPARATOR',($os == 'UNIX') ? '/' : '\\');

            }
            define('DS', \DIRECTORY_SEPARATOR);

            if (!defined('PATH_SEPARATOR'))
            {
                define('PATH_SEPARATOR', ($os == 'UNIX') ? ':' : ';');
            }
            define('PS', \PATH_SEPARATOR);

            if (!defined('APP_PATH'))
            {
                define('APP_PATH', dirname(dirname(__FILE__)));
                define('AP', APP_PATH);
            }
        }

DIRECTORY_SEPARATORDS 都正确定义了常量,如果我在这里回显它们,它们就可以正常工作。它的命名空间是 Feather\App。在Autoloader 类中,我使用DS 常量,它工作正常。 Autoloader 类位于同一个 Feather\App 命名空间中。

我正在运行 PHPUnit,并创建了这个测试 - 在 PHPUnit 的 setUp() 函数中调用了 setupEnv()

public function testAutoloadFunction()
    {
        $this->assertEquals(
            dirname(dirname(__FILE__)) . DS.'Components'.DS.'Collections'.DS.'Collection.php',
            \Feather\App\Autoloader::Autoload('\\Feather\\Components\\Collections\\Collection')
        );
    }

即使路径正确返回,也无法通过测试。它说:

Use of undefined constant DS - assumed 'DS'

所以,我的问题有很多背景故事 - 为什么这是一个错误?我想,好吧,也许我需要引用 \Feather\App\DS,但这会抛出这个:

PHP Fatal error: Undefined constant 'Feather\App\DS' in /web/Feather/Tests/AutoloaderTest.php

我认为常量是在全局范围内定义的,所以这不应该工作吗?如果没有,我该如何做才能让 PHPUnit 满意?如果我将use Feather\App 放在顶部,它仍然会失败并出现同样的assumed 'DS' 错误。

有人能解释一下吗?到目前为止,PHP 文档一直没有帮助!

【问题讨论】:

  • 你的一个观察结果一定是错误的。常量未定义,因此 setupEnv() 方法和/或 App 类未在单元测试之前运行。
  • 如果我尝试在setupEnv() 命令之前回显DS,它是空的/未定义的。如果我在setupEnv() 之后回显它,它就被定义了。这不是在其他地方定义的常量。因此,单元测试使用 DS 的正确值这一事实,我会反对。
  • 在整个单元测试方法中添加 assert('defined("DS")'); 以了解更多信息。并在init函数中添加print "setupEnv"进行调试。
  • 有趣,我刚刚在带有 WAMP 的 Windows 工作站上进行了测试,它可以工作......但在我的 Linux 工作站上,它失败了。今晚我会做更多的挖掘。
  • 好的 - 我不知道我做了什么,但它现在正在工作。我认为问题在于我没有检查if (!defined('DS')),当setUp() 函数在后续测试中运行时,它会导致问题。这是我最好的猜测。代码现在可以运行了!

标签: php namespaces constants


【解决方案1】:

我遇到了一个非常相似的问题,并通过以下步骤运行测试:

  1. 使用@runInSeparateProcess 注释标记测试

  2. 在测试类中覆盖run(),如下所示:

    公共函数运行(PHPUnit_Framework_TestResult $result = NULL){ $this->setPreserveGlobalState(false); 返回父级::run($result); }

  3. 将导致在测试文件中定义常量的require_once() 放入setUp()

    公共函数 setUp() { require_once DIR.'/SetUpEnv.php'; }

这可能不是一个理想的解决方法,但无疑总比没有解决方法好。

我从 StackOverflow 和/或其他地方的其他答案中抓取了一些零碎的东西(或者可能是整个东西),但是已经有一段时间了,所以对我在这里没有引用的来源表示歉意。

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2023-03-23
    • 2013-05-20
    • 2014-01-24
    • 2013-06-03
    相关资源
    最近更新 更多