【问题标题】:Can't Unit Test: $_SESSION empties before each test is ran无法进行单元测试:在运行每个测试之前 $_SESSION 清空
【发布时间】:2011-10-03 19:22:19
【问题描述】:

我无法对我的代码进行单元测试。

$_SESSION 会在每次运行下一个测试时清除。 当我运行 testStartProductSession() 时,我的对象将一些数据添加到 $_SESSION 变量中。但是当我运行下一个测试方法( testSessionIdIsKept() )时,$_SESSION 又是空的。

看起来 $_SESSION 在单元测试时变成了局部变量。

我不知道还能做什么。请检查以下输出:

// session_start() on bootrap.php;

class MC_Session_ProductTest extends PHPUnit_Framework_TestCase
{

    /**
     * @return MC_Session_Product
     */
    public function getObject()
    {
        // make getInstance() return new instance instead of singleton instance
        MC_Session_Product::$isUnityTest = true;
        $object = MC_Session_Product::getInstance();
        $object->getWsClient()->setServerListUrl(SERVER_LIST_URL);
        return $object;
    }

    /**
     * All tests pass
     * @depends testSetParam
     */
    public function testStartProductSession()
    {
        $developerId = PARAM_DEVELOPER_ID;
        $productCode = PARAM_PRODUCT_CODE;
        $productVersion = PARAM_PRODUCT_VERSION;
        $platform = PARAM_PLATAFORM;
        $deviceType = PARAM_DEVICE_TYPE;
        $locale = PARAM_LOCALE;

        try {
            $object = $this->getObject();
            $object->startSession($developerId, $productCode, $productVersion,
                                  $platform, $deviceType, $locale);
            $this->assertTrue($object->sessionStarted());
        } catch (Exception $e) {
            $this->fail('Fail to start session: ' . $object->getLastUrl());
        }

        echo "\$_SESSION in testStartProductSession(): ", print_r($_SESSION, 1);
        return $object;
    }

    /**
     * Test fails because $_SESSION is empty again
     * @depends testStartProductSession
     */
    public function testSessionIdIsKept(MC_Session_Product $lastObject)
    {
        echo "\$_SESSION in testSessionIdIsKept(): ", print_r($_SESSION, 1);
        $object = $this->getObject();
        // fails
        $this->assertTrue($lastObject->sessionStarted());
        $this->assertTrue($object->sessionStarted());
        $this->assertEquals($lastObject->getSessionId(), $object->getSessionId());
        return $object;
    }
}

/* ###### Output


$_SESSION in testStartProductSession():
Array
(
    [__MC] => Array
        (
            [MC_Session_Product] => Array
                (
                    [keyOne] => 'valueOne'
                    [sessionId] => 'someId'
                )

        )

)
$_SESSION in testSessionIdIsKept():
Array
(
)

*/

【问题讨论】:

    标签: php unit-testing phpunit


    【解决方案1】:

    您应该参数化每个函数需要的会话部分,而不是使 $_SESSION 成为单元测试的依赖项。然后,您可以轻松地模拟单元测试中的参数。以您当前尝试的方式执行此操作太难了,并且会使您的代码的可测试性降低。这将需要更改您当前的代码,但它会改进您的代码并使事情更具可测试性。

    【讨论】:

    • 嗯,这是我尝试进行单元测试的第一个项目。对于如何将 $_SESSION(一个数组)替换为模拟 object,我一点也不知道。我不能参考那个。您是否有任何实现该目标的代码示例?非常感谢您的帮助。
    【解决方案2】:

    PHPUnit 在每个测试方法之前将所有全局变量——包括$_SESSION——重置为它们的起始值。您可以通过将$backupGlobals 实例属性覆盖为false 来为测试用例禁用此功能。这不适用于 setUp() 方法。

    class MyTest extends PHPUnit_Framework_TestCase
    {
        protected $backupGlobals = FALSE;
    
        // ...
    }
    

    更多详情请参阅Global Variables and PHPUnit

    【讨论】:

    • 赞!像魅力一样工作。非常感谢!
    【解决方案3】:

    我会假设在每次测试之前都会调用一个方法。你可以在那里设置cookie。在 java 中,你有注解 @Before。

    【讨论】:

    • 在 PHPUnit 中创建一个名为 setUp() 的方法——与 JUnit 中的非注解方式相同。
    猜你喜欢
    • 2013-04-25
    • 1970-01-01
    • 2021-09-11
    • 2016-10-18
    • 2016-03-23
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多