Преодолевая принципы чистой архитектуры

Введение

Короче говоря, я проходил собеседование по поводу работы, и возникла интересная тема. Меня спросили, как вы проводите свои тесты… Я думаю, как и все, вы хотите продемонстрировать свой потенциал и сколько концепций и методов вы знаете и можете применить. Итак, я начал рассказывать об этом и в конце концов обнаружил, что они не используют насмешки ни в одном из своих тестов. Мы говорим от модуля к интеграции и E2E-тестированию…

Удивительно, но это интервью быстро превратилось в дискуссию о том, когда и стоит ли нам использовать Mocking в наших тестах, так что давайте послушаем:

Почему

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

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

Другой сценарий может заключаться в том, чтобы издеваться над всей вашей базой данных, вы хотите протестировать свой код и только свой код. Таким образом, вам все равно, доступна ли база данных или выполняется ли запрос на уровне ORM. Вам просто нужно убедиться, что вы выполняете правильные вызовы с соответствующими параметрами... У вас в голове появляется умная идея:
Давайте поиздеваться над нашим ORM или репозиторием. Таким образом, мы тестируем только нашу кодовую базу, не беспокоясь об инфраструктуре!
Это издевательство над вашей инфраструктурой…

Почему нет

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

AddUser(Пользователь-пользователь).Returns(1);
User test= new User(…);
int result=AddUser(test);
Console.WriteLine(result); //1

Этот результат будет возвращен без фактического вызова функции AddUser. Вы просто имитируете вызов с определенным результатом.

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

Допустим, вы изменили поведение или тип возвращаемого значения AddUser(). Ваш тест начнет давать сбои, и это совершенно нормально и «хорошо». Но то, что вы обнаружите, — это изменение туда и обратно и модификация части «Расстановка» вашего теста в соответствии с конкретным сценарием.

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

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

Далее, я знаю, что каждый слой тестов покрывает какие-то свои проблемы и регрессии, но иногда просто не имеет смысла издеваться и считается просто ленью. Быстрее просто смоделировать весь репозиторий, но так ли это выгодно?

Альтернатива

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

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