Следование TDD неизбежно ведет к DI?

14

Я научился выполнять тест-ориентированную разработку (TDD), внедрение зависимостей (DI) и инверсию управления (IoC) одновременно. Когда я пишу код с использованием TDD, я всегда использую DI в конструкторах моего класса. Мне интересно, если это из-за того, как я научился делать TDD, или это естественный побочный эффект TDD.

Поэтому мой вопрос таков: неизбежно ли следование принципам TDD и написание модульных тестов, которые не зависят от внешних служб, к DI?

жилль
источник
8
Я читаю «Искусство модульного тестирования», и кажется, что оно определенно приводит к инъекции зависимостей (DI).
программист
2
Так на каком языке это? DI / etc необходимы в Java, но это из-за языковых ограничений - в таких языках, как Python, это не нужно, поскольку они могут обезопасить зависимости в тестах.
Изката
@Izkata: я согласен, что DI - это обходной путь для ограничения языка; но monkeypatching не обязательно то же самое в менее жестких языках. Среди других способов я бы предпочел первоклассные функции, которые позволяют вам делать то, что DI приближает по дисциплине.
Хавьер

Ответы:

19

Следование TDD и написание модульных тестов, которые не зависят от баз данных или внешних сервисов, неизбежно ведут к DI?

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

Telastyn
источник
9

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

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

Карл Билефельдт
источник
8

Модульное тестирование приведет к DI (поскольку оно заставляет вас создавать слабосвязанные блоки). TDD не обязательно, так как TDD также может использоваться для создания тестов слой за слоем, вместо «дословных» модульных тестов. Смотрите эту статью

http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx

для объяснения различий.

Док Браун
источник
1
+1 за "TDD не UT". Также для признания того, что экстремальное расцепление является общим результатом UT, а не (обязательно) TDD.
Хавьер
3

Да и нет: TDD ведет к написанию хорошо структурированного кода, что само по себе ведет к DI.

Под этим я подразумеваю, что TDD обычно направляет вас в отношении инкапсуляции, SRP и возможности повторного использования. Речь идет не только о тестировании кода, а об использовании этих тестов для уточнения лучшего дизайна. Если объект создает свои собственные зависимости, то он живет в определенном контексте в определенном приложении и, вероятно, будет в большей степени вплетен в приложение. DI - хорошая вещь, не только с точки зрения тестирования, но и с точки зрения качества кода.

Тим
источник
Не могли бы вы уточнить, нет части вашего да и нет ответа? Как сделать TDD без DI.
Жиль
«Нет» - я не думаю, что это прямая связь между TDD и DI. Это косвенно через качество кода. Это, вероятно, раскалывает волосы, но я просто подумал, что хочу указать на качество кода, а не на тестируемость.
Тим
0

Как уже указывалось в других ответах, TDD не требует модульных тестов. Вы также можете написать интеграционные / функциональные тесты во время выполнения TDD. Из нескольких способов применения TDD создание модульных тестов может быть способом «подделка, пока вы не сделаете это» (подробности см. В книге Кента Бека).

Что касается «TDD неизбежно приводит к DI», это определенно не делает. При написании модульных тестов нужно изолировать тестируемый модуль от реализаций его внешних зависимостей. И это может быть сделано так же легко с или без DI. Вероятно, лучший способ - использовать подходящий инструмент изоляции / насмешки.

Рожерио
источник
Но чтобы использовать макеты, не обязательно ли вводить зависимости в классе?
Жиль