Я назвал вопрос в шутку, потому что уверен, что «это зависит», но у меня есть некоторые конкретные вопросы.
Работая с программным обеспечением, имеющим много глубоких уровней зависимости, моя команда привыкла довольно широко использовать макеты для отделения каждого модуля кода от зависимостей, находящихся под ним.
Поэтому я был удивлен, что Рой Ошеров предложил в этом видео, что вы должны использовать насмешку только в 5% случаев. Я предполагаю, что мы сидим где-то между 70-90%. Время от времени я видел и другие подобные указания .
Я должен определить то, что я считаю двумя категориями «интеграционных тестов», которые настолько различны, что им действительно нужно дать разные названия: 1) внутрипроцессные тесты, которые объединяют несколько модулей кода, и 2) внепроцессные тесты, которые говорят к базам данных, файловым системам, веб-службам и т. д. Меня интересует тип № 1 - тесты, которые интегрируют несколько модулей кода в процессе работы.
Большая часть рекомендаций сообщества, которые я прочитал, предполагает, что вы должны предпочесть большое количество изолированных, мелкозернистых модульных тестов и небольшое количество грубых сквозных интеграционных тестов, потому что модульные тесты дают вам точную обратную связь о том, где именно регрессии могли быть созданы, но грубые тесты, которые громоздки в настройке, фактически проверяют более сквозные функциональные возможности системы.
Учитывая это, представляется необходимым довольно часто использовать насмешки для изоляции этих отдельных блоков кода.
Дана объектная модель следующим образом:
... Также учтите, что глубина зависимости нашего приложения намного глубже, чем я мог бы уместить на этом изображении, так что между слоями 2-4 и 5-13 есть несколько слоев N.
Если я хочу проверить какое-то простое логическое решение, принимаемое в модуле № 1, и если каждая зависимость вводится конструктором в модуль кода, который зависит от него, так что, скажем, 2, 3 и 4 являются конструктором, вводимым в модуль 1 в изображение, я бы предпочел ввести макеты 2, 3 и 4 в 1.
В противном случае мне нужно будет создать конкретные экземпляры 2, 3 и 4. Это может быть более сложным, чем просто дополнительная печать. Часто 2, 3 и 4 будут иметь требования к конструктору, которые могут быть сложными для удовлетворения, и в соответствии с графиком (и в соответствии с реальностью нашего проекта), мне нужно будет построить конкретные экземпляры с N по 13, чтобы удовлетворить конструкторы 2, 3 и 4.
Эта ситуация становится более сложной, когда мне нужно 2, 3 или 4, чтобы вести себя определенным образом, чтобы я мог проверить простое логическое решение в # 1. Мне может понадобиться понять и «мысленно рассуждать» обо всем графе / дереве объектов сразу, чтобы заставить 2, 3 или 4 вести себя в нужном направлении. Часто кажется, что намного проще сделать myMockOfModule2.Setup (x => x.GoLeftOrRight ()). Returns (new Right ()); чтобы проверить, что модуль 1 отвечает, как ожидалось, когда модуль 2 говорит ему, чтобы он пошел правильно.
Если бы я тестировал конкретные экземпляры 2 ... N ... 13 вместе, установки теста были бы очень большими и в основном дублировались. Неудачные тесты могут не очень хорошо определить местонахождение неудач регрессий. Тесты не будут независимыми ( еще одна вспомогательная ссылка ).
Разумеется, зачастую целесообразно проводить тестирование нижнего уровня на основе состояния, а не на основе взаимодействия, поскольку эти модули редко имеют какую-либо дополнительную зависимость. Но кажется, что по определению издевательство почти необходимо, чтобы изолировать любые модули выше самого нижнего.
Учитывая все это, кто-нибудь может сказать мне, чего мне не хватает? Наша команда злоупотребляет издевательствами? Или, возможно, в типичном руководстве по модульному тестированию есть какое-то предположение о том, что уровни зависимости в большинстве приложений будут достаточно поверхностными, чтобы было действительно разумно протестировать все модули кода, объединенные вместе (что делает наш случай «особенным»)? Или, возможно, по-другому, наша команда не ограничивает наши ограниченные контексты адекватно?
Or is there perhaps some assumption in typical unit testing guidance that the layers of dependency in most applications will be shallow enough that it is indeed reasonable to test all of the code modules integrated together (making our case "special")?
<- Это.