Не удается выполнить модульный тест: $ _SESSION очищается перед запуском каждого теста

#php #unit-testing #phpunit

#php #модульное тестирование #phpunit

Вопрос:

Я не могу выполнить модульное тестирование своего кода.

$ _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
(
)

*/
  

Ответ №1:

Вместо того, чтобы делать $ _SESSION зависимостью для ваших модульных тестов, вы должны параметризовать части сеанса, необходимые каждой функции. Затем вы можете легко имитировать параметры в своем модульном тесте. Делать это текущим способом, который вы пытаетесь, слишком сложно и делает ваш код менее проверяемым. Это потребует изменения вашего текущего кода, но это улучшит ваш код и сделает его более тестируемым.

Комментарии:

1. Что ж, это первый проект, который я пытаюсь выполнить модульное тестирование. У меня нет ни малейшего представления о том, как я мог бы заменить $ _SESSION (массив) на макет объекта . Я не могу ссылаться на это. Есть ли у вас какой-либо пример кода, который достигает этой цели? Большое вам спасибо за вашу помощь.

Ответ №2:

PHPUnit сбрасывает все глобальные переменные, включая $_SESSION их начальные значения, перед каждым методом тестирования. Вы можете отключить это для тестового примера, переопределив свойство $backupGlobals instance на false . Это не работает из setUp() метода.

 class MyTest extends PHPUnit_Framework_TestCase
{
    protected $backupGlobals = FALSE;

    // ...
}
  

Дополнительные сведения см. в разделе Глобальные переменные и PHPUnit .

Комментарии:

1. Слава! Сработало как шарм. Большое вам спасибо!

Ответ №3:

Я бы предположил, что существует метод, который вызывается перед каждым тестом. Вы можете настроить cookie там. В java у вас есть аннотация @Before .

Комментарии:

1. В PHPUnit вы создаете метод с именем setUp() — таким же, как способ без аннотаций в JUnit.