константа абстрактного класса phpunit - PullRequest
3 голосов
/ 20 октября 2011

Я пытаюсь найти способ проверить абстрактную константу класса, которая должна существовать и совпадать / не совпадать со значением. Пример:

// 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 Ответ

0 голосов
/ 20 октября 2011

Во-первых, реорганизуйте вызов 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.');
    }
}
...