Моя цель состоит в том, чтобы иметь возможность писать модульные тесты для методов c, которые поддерживают:
- Поддерживаемость - я хочу, чтобы код был таким же простым для понимания, понимания и отладки с течением времени ,
- Производительность - я бы хотел, чтобы скорость наших тестов не пострадала из-за технического долга, если это возможно.
Ограничения: Мы не можем изменить метод stati c, чтобы метод экземпляра. Это было бы первым, что я бы, вероятно, предложил, но я ищу варианты / альтернативы и мнения.
Тестирование методов stati c - это немного больно. Было время, когда мы могли сделать это с помощью phpunit. В Mockery есть средства для тестирования stati c методов * от 1012 * до aliasing , но это не рекомендуется. Я обнаружил, что выполнение этих типов тестов может быть очень медленным. (отсюда и цель № 2).
К сожалению, если у вас есть достаточное количество кода, основанного на другом коде с использованием методов stati c, вы можете рассчитывать на собственный долг. Существуют некоторые методики, использующие call_user_func
(https://medium.com/@nihon_rafy / методики для моделирования c -методов для юнит-тестов-в-php -18b2a11458d0 ) и forward_static_call_array()
(http://miljar.github.io/blog/2014/01/29/phpunit-testing-static-calls/), но мне трудно следовать этому коду.
Я хочу предоставить альтернативную опцию динамического c, аналогичную приведенной выше.
class LegacyClass {
public static function staticMethod($a, $b, $c) {
return QueryBuilder::where($a, $b, $c)->getAll();
}
}
class ClassToTest {
public function test($a, $b, $c) {
return LegacyClass::staticMethod($a+1, $b+2, $c+3);
}
изменяется на это =>
class LegacyClass {
public static function staticMethod($a, $b, $c) {
return QueryBuilder::where($a, $b, $c)->getAll();
}
}
class ClassToTest{
// @var string fully qualified class name
private $legacyClass = LegacyClass::class;
public function test($a, $b, $c) {
return {$this->legacyClass}::staticMethod($a+1, $b+2, $c+3);
}
Теперь, с учетом вышеизложенного, мы можем смоделировать LegacyClass
, получить имя класса этого макета и использовать Reflection
для установки приватного $legacyClass
переменная.
При этом мои вопросы:
- Какой из перечисленных выше вариантов является наиболее приемлемым решением?
- Существуют ли лучшие альтернативы, которые соответствуют заявленные цели? (Если так, я могу добавить)
Спасибо за ваш вклад!