Информация по теме

Цель: Познакомиться с использованием заглушек и фиктивных объектов в рамках модульных тестов.

Материалы для подготовки

Презентация

Код, написанный на занятии можно скачать по данной ссылке. Для распаковки архива используйте команду 7z x 02-2017-09-code.7z.

Немного теории

Во время написания модульных тестов нам необходимо добиться изоляции тестируемого кода от дргугого кода. В противном случае в рамках теста вы тестируете не только метод класса, но также и его зависимости.

В Ruby ваш код может содержать следующие зависимости:

  • Глобальные переменные.
  • Константы.
  • Методы классов.
  • Ссылки на объекты и их методы.

С глобальными переменными всё просто - ваш код не должен зависеть от них, он должен только лишь управлять своим собственным статусом, не более того.

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

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

Объекты классов, от которых зависит код могут придти из следующих источников:

  • Тестируемый класс самостоятельно создаёт объекты другого класса.
  • Ссылки на объекты данному классу передаются извне.

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

Фреймворк Minitest предоставляет два инструмента для изоляции: метод Object.stub, позволяющий переопределить методы класса, а также класс Mock, позволяющий создать фиктивный объект и проверить свойства. Библиотека Mocha предоставляет расширенные возможности по описанию фиктивных объектов.

Согласно Мартину Фаулеру можно выделить следующие фиктивные объекты, которые можно использовать при написании модульных тестов:

  • Пустышка, dummy. Следует применять в том случае, если тестируемый метод не использует его методы, а ему только необходима ссылка на объект.
  • Подделка, fake. Данные объекты имеют реализацию метода, однако упрощённую для целей тестирования.
  • Заглушка, stub. Объекты предоставляют методы, которые возвращают заранее указанные ответы.
  • Шпионы, spy. Объекты позволяют анализировать параметры, которые были переданы в рамках тестируемого кода.
  • Пародии?, mock. Объекты проверяют в рамках теста, были ли вызваны методы, были ли корректно переданы им аргументы. Если вызовы не совпадают с указанной спецификацией, тогда данный объект сообщает о нарушении контракта.

Практическое занятие

Цель занятия: научиться изолировать свои модульные тесты от внешних зависимостей.

Задача: напишите модульные тесты для задачи №5 пункта 2.1 задачника. Реализацию тестов начните с подсистемы ввода-вывода из файла и консоли.