Sylph: Глубокие Stub-ы для тестов от создателей PHPixie, или как конвертировать массив в класс

в 18:00, , рубрики: mock, php, phpixie, tdd, метки: , , ,

Юнит тестинг Sylph
Одной из самых нужных вещей при написании юнит тестов является создание mock-ов и stub-ов для объектов которые используются тестируемым классом. Здесь стоит упомянуть о важном отличии: если «mock» является исходным объектом в котором замены одна или несколько методов, то «stub» это некий фейк который полностью заменяет исходный объект. в зависимости от сценария иногда намного легче создать стаб чем сделать подходящий mock. В этой статья я покажу как эффективно и быстро создавать стабы используя небольшой класс Sylph от создателей фреймворка PHPixie.

Иногда случаются случаи когда тестируемый метод использует глубокие проперти объекта например:

class Fairy{

       public $name;
       protected $home_tree;

       public function __construct($name, $home_tree){
             $this->name = $name;
             $this->home_tree = $home_tree;        
       }
      
       // фея дружит со всеми зайками которые живут в ее лесе
       // и белками в ее дереве
       public function get_friends(){
            $friends = $this->home_tree->num_squirrels;
            $friends += $this->home_tree->forest->num_animals('bunny'));
            return $friends;
       }

При написании теста для такого класса пришлось бы мокать классы Tree и Forest, связывать их друг с другом и передавать в конструктор. И все ради вызова одной функции.

Sylph позволяет сделать это намного проще, используя простые ассоциированные массивы и анонимные функции. В нашем случае мы могли бы описать $home_tree как:

$sylph = new PHPixieSylph();

$home_tree = $sylph->cast(array(
     'num_squirrels' => 5,
     'forest' => $sylph->cast(array(
                           'num_animals' => function($animal){
                                if($animal == 'bunny')
                                   return 4;

                                throw new Exception('Animal not found');
                           }
                     ))
));

Такой подход имеет ряд преимуществ, в первую очередь намного лучшая читабельность и лаконичность.
Кстати использование анонимных функций позволяет делать довольно интересные операции, например менять параметры на лету:


$num_bunnies = 5;

$bunnies = $sylph->cast(array(
      'add' => function($new) use($num_bunnies){
                return $new + $num_bunnies;
       }
));

$bunnies->add(1); // 6
$bunnies->add(2); // 7

$num_bunnies = 2;

$bunnies->add(1); // 3
$bunnies->add(2); // 4

Как всегда разработчики PHPixie стараются найти самое простое решение проблемы.

Автор: jigpuzzled

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js