// codeart.ru / Главная / Рекомендации по написанию тестов с применением моков Форум

Рекомендации по написанию тестов с применением моков rss подписка

Автор: Evgeny Sergeev

Сегодня прочитал интересную статью The Virtues of Mockery: A mock is like a stub with attitude. В ней Noel Rappin приводит несколько рекомендаций, которые он использует в процессе написания тестов с применением моков.

В моем вольном переводе они выглядят так:

1. Все внешнее окружение тестируемого метода должно быть представлено моками;

2. Внесение одной ошибки в тестируемый код не должно приводить к провалу более чем одного теста;

3. Используйте созданные моки для информирования о структуре программы.

Попытаюсь немного осмыслить полученную информацию. Больше всего вопросов вызывает вторая рекомендация, которая по сути призывает изолировать каждый метод в отдельном тесте с собственным окружением.

Допустим, у нас есть класс, в котором есть несколько методов, способных изменить состояние объекта. Если методы независимы от текущего состояния объекта, то можно проверить их по отдельности в двух разных тестах. Тогда внесение ошибки в один метод будет приводить к провалу только одного теста.

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

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

Например, есть класс phpbb_poster, который отвечает за публикацию постов в phpbb форум. У него есть публичные методы login, publish_post, get_categories, logout. Получается, что все функции завязаны на login, поэтому ошибка в этой функции приведет к провалу всех тестов этого класса. Самое простое и самое неправильное решение - включить все методы в один тест. Но тогда тест получится раздутым и малопонятным, а этого хотелось бы избежать. Тем более, проблема здесь явно в неправильной архитектуре класса Phpbb_poster.

В приведенном примере проблема легко решается путем вынесения функции login в отдельный класс Phpbb_session с методами login, logout. Объект этого класса является источником данных для функций класса Phpbb_poster. В результате замены Phpbb_sedsion на мок (первая рекомендация) методы publish_post и get_categories могут быть протестированны отдельно.

Возникает вопрос, всегда ли зависимость от какой-то одной функции является проблемой архитектуры? Мне кажется, что да. Я пытался придумать другие примеры, где для успешного тестирования требуется объединить все методы в один тест, но во всех случаях приходил к выводу, что проблему можно решить с помощью инверсии зависимостей.

  1. Почему-то меня совсем перестали комментировать | Блог Жени Сергеева

Leave a Reply

« Нужно ли при первичной разработке теста искать наборы данных, приводящих к коллизии Очень нужна помощь в написании теста »