O seguimento do TDD leva inevitavelmente ao DI?

14

Aprendi a fazer o desenvolvimento orientado a testes (TDD), injeção de dependência (DI) e inversão de controle (IoC), tudo ao mesmo tempo. Quando escrevo código usando TDD, sempre acabo usando DI nos construtores da minha classe. Eu estou querendo saber se isso é por causa de como eu aprendi a fazer TDD, ou se este é um efeito colateral natural do TDD.

Portanto, minha pergunta é a seguinte: Seguir os princípios do TDD e escrever testes de unidade que não dependem de serviços externos levam inevitavelmente ao DI?

Gilles
fonte
8
Estou lendo A arte do teste de unidade e parece que isso definitivamente leva à injeção de dependência (DI).
programador
2
Então, que idioma é esse? DI / etc são necessários em Java, mas isso é devido a uma limitação de linguagem - linguagens como Python não precisam disso, pois podem ocultar as dependências dos patches nos testes.
Izkata
@ Izkata: Concordo que o DI é uma solução alternativa para uma limitação de idioma; mas o monkeypatching não é necessariamente a mesma coisa em idiomas menos rígidos. Entre outras formas, eu preferiria funções de primeira classe, que permitem fazer naturalmente o que o DI se aproxima por disciplina.
21412 Javier

Respostas:

19

Seguir TDD e escrever testes de unidade que não dependem de bancos de dados ou serviços externos inevitavelmente levam a DI?

Para definições amplas de DI, sim. As aulas não existem no vácuo, portanto, elas precisam ter suas dependências preenchidas de alguma forma. Às vezes, apenas fornecer um valor é bom. Às vezes, você precisa fornecer uma simulação no construtor. Às vezes via contêineres IoC. Às vezes, via acessador de teste privado. Está tudo injetando alguma coisa de teste na classe para que possa funcionar isoladamente.

Telastyn
fonte
9

Para pessoas que já conhecem o DI, mas nunca entenderam o ponto, acho que o teste de unidade quase sempre leva ao uso do DI.

Se você não conhece a DI e está tentando escrever testes de unidade, algumas pessoas naturalmente a reinventam, outras ficam frustradas e eventualmente descobrem a DI através de pesquisas, mas você ficaria surpreso com a frequência com que isso simplesmente não ocorre a alguém que pode haver uma maneira melhor de arquitetar seu software para facilitar o teste de unidade. Essas pessoas consideram o teste de unidade intratável e desistem.

Karl Bielefeldt
fonte
8

O teste de unidade levará ao DI (uma vez que obriga a criar unidades fracamente acopladas). TDD não necessariamente, uma vez que o TDD também pode ser usado para criar testes camada por camada, em vez de testes de unidade "textuais". Veja este artigo

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

para uma explicação das diferenças.

Doc Brown
fonte
1
+1 para "TDD não é UT". Também por reconhecer que o desacoplamento extremo é um resultado comum da UT, não (necessariamente) do TDD.
Javier
3

Sim e não: TDD leva a escrever código bem estruturado, o que leva a DI.

Com isso, quero dizer que o TDD geralmente envia o caminho certo em relação ao encapsulamento, SRP e reutilização. Não se trata apenas de realizar alguns testes em seu código: trata-se de usá-los para aprimorar um design melhor. Se um objeto cria suas próprias dependências, ele está vivendo dentro de um contexto específico dentro de um aplicativo específico e provavelmente será incorporado ao aplicativo em maior grau. A DI é uma coisa boa, não apenas do ponto de vista de teste, mas também do ponto de vista da qualidade do código.

Tim
fonte
Você poderia esclarecer a parte não do seu sim e não responder? Como se faz TDD sem DI.
Gilles
Sendo a parte "não", não acho que seja uma ligação direta entre TDD e DI. É indireto via qualidade do código. O que provavelmente está dividindo os cabelos, mas pensei em salientar que a qualidade do código é o que você deseja, não apenas a testabilidade.
Tim
0

Como já apontado em outras respostas, o TDD não requer testes de unidade . Você também pode escrever testes de integração / funcionais enquanto faz TDD. Das várias maneiras de aplicar o TDD, a criação de testes de unidade seria do tipo "fingir até você fazer" (consulte o livro de Kent Beck para obter detalhes).

Quanto a "TDD inevitavelmente leva a DI", definitivamente não. O que é necessário ao escrever testes de unidade é isolar a unidade que está sendo testada das implementações de suas dependências externas. E isso pode ser feito com a mesma facilidade, com ou sem DI. A melhor maneira, provavelmente, é usar uma ferramenta adequada de isolamento / zombaria.

Rogério
fonte
Mas para usar zombarias, você não deve necessariamente injetar as dependências da classe?
Gilles