Поскольку я тут продолжаю писать про тестирование, не могу не упомянуть о прекрасной библиотеке Mockery. Это отличная реализация мок-объектов, которой в разы удобнее пользоваться, в сравнении со средствами PHPUnit, по крайней мере.
Чтобы получить Mockery в проект, надо в блок require
в composer.json
вписать вот такую вот строчку:
1 2 3 |
|
Сами авторы пока что советуют не привязываться к конкретной версии, хотя теги в репозитории есть (на момент написания заметки самая свежая версия — 0.7.2). Очевидно, проект еще не очень стабилен, но в любом случае очень удобен. Используется он например вот так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
В приведенном блоке кода я использую весь тот функционал Mockery, который в приципе необходим в большинстве тестов.
Обратите внимание, какой симпатичный (и человекопонятный!) у Mockery API: все методы называются так, как они и должны называться, все нужное выведено в статические функции у легкодоступного класса, словом — сказка, а не моки.
Собственно, что к чему в коде.
Метод mock('\Имя\Класса\Как\Строка')
дает нам мок-объект, над которым мы впоследствии можем всячески издеваться. shouldReceive('имяМетода')
добавляет в мок ожидание и возвращает его в стиле fluent interface. Этот самый fluent interface позволяет настроить ожидание.
Метод ожидания with()
принимает как точные значения параметров, так и Matcher
. Matcher
по сути является вот таким куском кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Видим, что путем нехитрого колдовства тут проверяется входящее значение, и оно может принадлежать либо к одному из стандартных типов (тех, которые проверяются методами is_bool
, is_string
и т.д.), либо являться экземпляром класса или экземпляром реализации какого-либо интерфейса, либо вовсе быть функцией.
Также в создании $geocoderMock
я после вызова shouldReceive()
указываю, что метод using
в имитируемом классе должен быть вызван один раз. И делаю это простым вызовом \Mockery\Expectation::once()
, что несомненно куда как приятнее, чем стиль PHPUnit. А вот кстати полный набор методов для указания количества вызовов.
С методом andReturn()
, думаю, все понятно — он принимает очередь параметров. В моем случае очередь состоит всегда из одного параметра, потому что тестируется достаточно простой функционал, не требующий особых танцев с бубном.
Ну и небольшой нюанс в том, что после объявления ожиданий мока последним значением, вернувшимся в нашем fluent interface, является ожидание, а не сам мок, поэтому в конце вызова нужно вызвать еще и метод \Mockery\Expectation::getMock()
.
Конечно, это ваше дело, чем пользоваться — Mockery или средствами, встроенными в PHPUnit, но все же мне кажется, что эта библиотека более чем достойна упоминания.