🗂 Автоматическое тестирование логирования
Честно говоря, раньше я даже и не задумывался о том, что журналирование может быть необходимо тестировать...
Каждый из нас может оказаться в ситуации, когда требуется реализовать логи каких-то критических (с точки зрения бизнеса) мест в коде. Такие логи могут быть особенно полезны для службы поддержки. На них могут строиться какие-то аналитические сервисы и прочие вещи, что требует их защиты от изменений в будущем... Подобного вида логи отличаются от привычных каждому логов, помогающих реализовывать отладку проекта. Так у нас появляется понятие двух различных типов логирования: служебные (для бизнесса) и диагностические (для программиста).
Диагностические логи являются деталью имплементации и в целом-то тестироваться и не должны. Однако со служебными логами дела обстоят куда интереснее. Служебные логи — требование бизнеса, а следовательно они являются наблюдаемым поведением. В этом случае наша главная задача — гарантировать их неизменность.
Система журналирования является внешней неуправляемой зависимостью. Поэтому мы будем заменять её моком при тестировании, и в интеграционном тесте проверять взаимодействие нашего приложения с этой зависимостью.
Для того, чтобы что-то мокнуть, нам нужен интерфейс. Более того, вам стоит создать доменный логер, у которого будут чётко определенные бизнес-методы, например DomainLogger.UserEmailHasChanged, а не какой-нибудь Printf. Создав интерфейс для доменного логера, вы можете без особых проблем создать мок и использовать его в тестах для проверки взаимодействия.
Если вы создаёте логи в контроллере, всё в вашей жизни прекрасно. Но что если вам вдруг понадобилось создать служебный лог внутри слоя бизнес-логики? Наличие внепроцессорных зависимостей внутри домена переусложняет его и делает невозможным его юнит-тестирование. Для решения данной проблемы стоит все логи создавать в контроллере. Для того, чтобы вынести служебное логирование из бизнес слоя в контроллер, можно прибегнуть к событиям. Внутри доменного слоя вы создаёте события, а внутри контроллера проходитесь по ним и обрабатываете (логируете). Таким образом вы имеете возможность легко проверить события, полученные доменом, в юнит тестах, а в интеграционных тестах проверить их обработку контроллером. Диагностическое логирование в слое бизнес логики лучше вовсе опустить.
За более подробным объяснением с примерами кода обращайтесь к главе 8.6 книги Владимира Хорикова "Принципы юнит-тестирования"
Честно говоря, раньше я даже и не задумывался о том, что журналирование может быть необходимо тестировать...
Каждый из нас может оказаться в ситуации, когда требуется реализовать логи каких-то критических (с точки зрения бизнеса) мест в коде. Такие логи могут быть особенно полезны для службы поддержки. На них могут строиться какие-то аналитические сервисы и прочие вещи, что требует их защиты от изменений в будущем... Подобного вида логи отличаются от привычных каждому логов, помогающих реализовывать отладку проекта. Так у нас появляется понятие двух различных типов логирования: служебные (для бизнесса) и диагностические (для программиста).
Диагностические логи являются деталью имплементации и в целом-то тестироваться и не должны. Однако со служебными логами дела обстоят куда интереснее. Служебные логи — требование бизнеса, а следовательно они являются наблюдаемым поведением. В этом случае наша главная задача — гарантировать их неизменность.
Система журналирования является внешней неуправляемой зависимостью. Поэтому мы будем заменять её моком при тестировании, и в интеграционном тесте проверять взаимодействие нашего приложения с этой зависимостью.
Для того, чтобы что-то мокнуть, нам нужен интерфейс. Более того, вам стоит создать доменный логер, у которого будут чётко определенные бизнес-методы, например DomainLogger.UserEmailHasChanged, а не какой-нибудь Printf. Создав интерфейс для доменного логера, вы можете без особых проблем создать мок и использовать его в тестах для проверки взаимодействия.
Если вы создаёте логи в контроллере, всё в вашей жизни прекрасно. Но что если вам вдруг понадобилось создать служебный лог внутри слоя бизнес-логики? Наличие внепроцессорных зависимостей внутри домена переусложняет его и делает невозможным его юнит-тестирование. Для решения данной проблемы стоит все логи создавать в контроллере. Для того, чтобы вынести служебное логирование из бизнес слоя в контроллер, можно прибегнуть к событиям. Внутри доменного слоя вы создаёте события, а внутри контроллера проходитесь по ним и обрабатываете (логируете). Таким образом вы имеете возможность легко проверить события, полученные доменом, в юнит тестах, а в интеграционных тестах проверить их обработку контроллером. Диагностическое логирование в слое бизнес логики лучше вовсе опустить.
За более подробным объяснением с примерами кода обращайтесь к главе 8.6 книги Владимира Хорикова "Принципы юнит-тестирования"