reflection на статический вызов

ksnk

прохожий
Требуется написать кучку тестов на объект, активно использующий статические вызовы класса-хелпера. Для этого требуется подменить класс-хелпер на отладочный. Тоесть, что бы в конструкции
PHP:
OBJECT::method(...)
вместо класса OBJECT вызвался тестовый класс, ведущий учет и контроль. Пока придумался только метод с подменой класса через автолод. Создается класс с таким же именем, но автолодится он из отладочного места. Есть ли более другие способы для такого финта?
 

ksnk

прохожий
Спасибо.
К сожалению, модифицировать php, добавляя расширения, не очень подходит. Нужно, в принципе, обеспечить запуск тестов локально на разных машинах разработчиков.
Выяснилось, что класс-хелпер велик, могуч и постоянно дописывается. Тоесть полностью скопировать интерфейс не представляется разумным. К счастью нужно подменить только несколько методов.
Применяется пока такой финт. Основной хелпер-класс копируется в тестовый каталог, текстовым поиском его имя в файле заменяется на PARENT_OBJECT. В тестовой оболочке описан класс OBJECT унаследованный от PARENT_OBJECT. Вроде, пока, работает.
 

ksnk

прохожий
флоппик, делается рефакторинг одного из то узлов большой системы. Как без тестов?
Подготовка (Копирование) производится отдельным скриптом, не часто. Тесты гоняются phpunit'ом.
 

fixxxer

К.О.
Партнер клуба
PHP:
class /* original class name: Helper */ ShittyHelper {
    public static function foo($a) {
        return ['foo', $a];
    }
    public static function bar($a) {
        return ['bar', $a];
    }
}

final class Helper {
    private static $mockInstance = null;

    private function __construct() {}
    private function __clone() {}

    public static function registerMockInstance($mockInstance) {
        self::$mockInstance = $mockInstance;
    }

    public static function __callStatic($method, array $args) {
        if (self::$mockInstance && method_exists(self::$mockInstance, $method)) {
            return call_user_func_array([self::$mockInstance, $method], $args);
        } else {
            return call_user_func_array(['ShittyHelper', $method], $args);
        }
    }
}

class HelperMock {
    public function foo($a) {
        return ['mocked_foo', $a];
    }
}

assert(['foo', 1] == Helper::foo(1));
assert(['bar', 1] == Helper::bar(1));

Helper::registerMockInstance(new HelperMock);

assert(['mocked_foo', 1] == Helper::foo(1));
assert(['bar', 1] == Helper::bar(1));
 
  • Like
Реакции: ksnk

ksnk

прохожий
fixxxer, можно и так, вместо наследования. Хотя этот вариант не отменяет этап подготовки. С копированием и переименованием.
 

fixxxer

К.О.
Партнер клуба
Почему? Один раз переименовать класс, в тот же файл добавить враппер, и оставить как есть имя файла. Оно ж не мешает. И все равно такое надо рефакторить - если при рефакторинге есть желание сохранить BC, то там какой-то callStatic-фасад в laravel-стиле и получится в итоге
 

ksnk

прохожий
Ну как это - не мешает? Все вызовы хелпера в боевом использовании будут идти через затычку? PHP - не С, тут будет тормозить. Тут я такого пока еще боюсь-боюсь.
 

ksnk

прохожий
Absinthe, это про запуск тестов? Скорость тестирования для меня не настолько важна, она вполне устраивает. Меня беспокоит скорость выполнения основного скрипта при модификации класса-хелпера, предложенной fixxxer. Насколько я понял, предлагается оборачивать каждый вызов хелпера в отдельную функцию с условием. Для тестирования оно и неплохо, а для нормальной жизни?
 

fixxxer

К.О.
Партнер клуба
Ну как это - не мешает? Все вызовы хелпера в боевом использовании будут идти через затычку? PHP - не С, тут будет тормозить. Тут я такого пока еще боюсь-боюсь.
Если таких вызовов не по 100500 на запрос, разницы не будет.
 

ksnk

прохожий
Ok. Третье перечисленное тут расширение для php. Надо будет познакомиться
Если таких вызовов не по 100500 на запрос, разницы не будет.
Может быть, хотя сомнения остаются... В скорострельность PHP я настолько пока не верю :)
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Никто не заставляет верить.
Меняешь, гоняешь siege-м, смотришь. :)
 
Сверху