Искусство тестирования контроллеров в .NET: теория что, как и почему

Привет! Одной из распространенных проблем при создании некоторых веб-приложений является тестирование контроллеров. Если у вас есть какие-то вопросы по этому поводу — сегодня вы можете найти ответы! Мы сосредоточимся на темах, почему важно тестировать контроллеры и почему мы должны делать их тонкими. Далее мы перейдем к тому, что на самом деле тестировать в контроллере, и мы слегка коснемся тестирования сериализации. Готовый? Идти!

Зачем вообще тестировать контроллеры?

Потому что они являются важной частью любого веб-приложения — они являются точкой входа для внешнего мира в нашу область. Ответственность контроллеров состоит в том, чтобы получать и отвечать по протоколу HTTP — и это единственная обязанность, которую мы должны протестировать. На этой части стоит сделать сильный акцент — контроллеры должны быть тонкими. Бизнес-логика должна оставаться за их пределами, включая делегирование проверки и бизнес-логики отдельным классам. Во время тестирования контроллера мы не хотим смешивать контексты.

Что тестировать?

Есть несколько вариантов:

  • Маршрутизация: это гарантирует, что мы правильно сопоставляем действия с маршрутами, даже если это делается фреймворком, мы можем забыть некоторые регистрации или параметры — этот тест гарантирует, что мы действительно можем достичь конечной точки.
  • Взаимодействие с базовыми валидаторами, службами и другими классами бизнес-логики: давайте проясним, мы хотим протестировать вызов правильных методов с полученными значениями, а НЕ вывод этих соавторов! Если мы хотим протестировать контроллеры, мы должны имитировать зависимости и проверять только взаимодействия, ничего больше!
  • State Base тестирует код состояния ответа и возможно полезную нагрузку: мы хотим убедиться, что мы возвращаем коды состояния и сообщения, правильно закодированные, сжатые и т. д. Опять же, мы не можем не подчеркнуть здесь — вывод можно законсервировать, использовать заглушки и макеты, не тестируйте полный вертикальный срез системы со всеми зависимостями здесь, или вы больше не тестируете контроллер, вы должны провести сквозное тестирование.

Что это за взаимодействие и состояние-база?

Более подробно мы уже говорили об этом в этой записи блога. Краткое содержание:

  • Тесты взаимодействий сосредоточены на совместной работе таких классов, как сервисы и репозитории. Целью их является проверка контракта и потока вызовов и параметров передачи, не фокусируясь на фактических результатах обработки. Эти тесты обычно более хрупкие, но дают нам хорошее руководство при реализации проекта.
  • Тесты на основе состояния не заботятся о соавторах, единственное, что мы проверяем с ними, — это конечное состояние/вывод тестируемого модуля. Тестировать контроллеры с ними — это здорово, так как в итоге конечный ответ от контроллера всегда должен быть одинаковым, например, код состояния 200 и объект JSON, независимо от того, как мы туда попали и какая логика стояла за этим процессом.

И тестировать нам нужно и то, и другое — если мы изменим дизайн, наш тест взаимодействия сломается, а тест на основе состояний гарантирует, что в конечном итоге поведение останется прежним, даже если мы полностью изменим внутреннюю логику.

Тестирование сериализации

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

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

Краткое напоминание о том, что тестировать:

  • Коды состояния
  • Полезная нагрузка (если не сложно)
  • Конфигурация JSON (НЕ сериализация, доверьтесь библиотеке!)

Удачного кодирования!