¿Seguir TDD inevitablemente conduce a DI?

14

Aprendí a hacer Test Driven Development (TDD), Dependency Injection (DI) e Inversion of Control (IoC), todo al mismo tiempo. Cuando escribo código usando TDD, siempre termino usando DI en los constructores de mi clase. Me pregunto si esto se debe a cómo aprendí a hacer TDD, o si este es un efecto secundario natural de TDD.

Entonces mi pregunta es esta: ¿Seguir los principios de TDD y las pruebas de unidad de escritura que no dependen de servicios externos conducen inevitablemente a DI?

Gilles
fuente
8
Estoy leyendo The Art of Unit Testing y parece que definitivamente conduce a la inyección de dependencia (DI).
programador
2
Entonces, ¿de qué idioma se trata? DI / etc son necesarios en Java, pero eso se debe a una limitación de idioma: los lenguajes como Python no lo necesitan, ya que pueden modificar las dependencias de parches en las pruebas.
Izkata
@Izkata: estoy de acuerdo en que DI es una solución para una limitación de idioma; pero monkeypatching no es necesariamente lo mismo en lenguajes menos rígidos. Entre otras formas, preferiría funciones de primera clase, lo que le permite hacer naturalmente lo que DI se aproxima por disciplina.
Javier

Respuestas:

19

¿Seguir las pruebas de TDD y de unidad de escritura que no dependen de bases de datos o servicios externos conduce inevitablemente a DI?

Para definiciones amplias de DI, sí. Las clases no existen en un vacío, por lo que necesitan tener sus dependencias llenas de alguna manera. A veces, simplemente proporcionar un valor está bien. A veces necesitas proporcionar un simulacro en el constructor. A veces a través de contenedores IoC. A veces a través de un acceso de prueba privado. Todo está inyectando algo de prueba en la clase para que pueda funcionar de forma aislada.

Telastyn
fuente
9

Para las personas que ya conocen la DI, pero que nunca han visto el punto, creo que las pruebas unitarias conducirán casi invariablemente al uso de la DI.

Si no sabe sobre DI y está tratando de escribir pruebas unitarias, algunas personas reinventarán naturalmente la DI, algunas se frustrarán y eventualmente la descubrirán a través de la investigación, pero se sorprenderá de la frecuencia con la que simplemente no se le ocurrirá a alguien que podría haber una mejor manera de diseñar su software para facilitar las pruebas unitarias. Esas personas descartan las pruebas unitarias como intratables y se rinden.

Karl Bielefeldt
fuente
8

Las pruebas unitarias conducirán a DI (ya que te obliga a crear unidades sueltas). TDD no necesariamente, ya que TDD también se puede utilizar para crear pruebas capa por capa, en lugar de pruebas unitarias "textuales". Ver este artículo

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

para una explicación de las diferencias.

Doc Brown
fuente
1
+1 para "TDD no es UT". También para reconocer que el desacoplamiento extremo es un resultado común de UT, no (necesariamente) de TDD.
Javier
3

Sí y no: TDD lleva a escribir código bien estructurado, que a su vez conduce a DI.

Con eso quiero decir que TDD generalmente le envía la forma correcta con respecto a la encapsulación, SRP y reutilización. No se trata solo de obtener algunas pruebas de su código: se trata de usar esas pruebas para desarrollar un mejor diseño. Si un objeto crea sus propias dependencias, entonces está viviendo dentro de un contexto específico dentro de una aplicación específica y es probable que esté entretejido en la aplicación en mayor grado. DI es algo bueno, no solo desde el punto de vista de la prueba, sino también desde el punto de vista de la calidad del código.

Tim
fuente
¿Podría aclarar la no parte de su respuesta de sí y no? ¿Cómo se hace TDD sin DI?
Gilles
La parte 'no' es que no creo que sea un vínculo directo entre TDD y DI. Es indirecto a través de la calidad del código. Lo que probablemente está dividiendo pelos, pero solo pensé en señalar que la calidad del código es lo que busca, no solo la capacidad de prueba.
Tim
0

Como ya se señaló en otras respuestas, TDD no requiere pruebas unitarias . También puede escribir pruebas de integración / funcionales mientras hace TDD. De las varias formas de aplicar TDD, la creación de pruebas unitarias sería la forma "fingir hasta que lo consigas" (ver el libro de Kent Beck para más detalles).

En cuanto a "TDD inevitablemente conduce a DI", definitivamente no lo hace. Lo que se necesita al escribir pruebas unitarias es aislar la unidad que se está probando de las implementaciones de sus dependencias externas. Y esto se puede hacer con la misma facilidad con o sin DI. La mejor manera, probablemente, es usar una herramienta de aislamiento / burla adecuada.

Rogério
fuente
Pero para usar simulacros, ¿no debes inyectar necesariamente las dependencias en la clase?
Gilles