Eu tenho uma classe que é refatorada em 1 classe principal e 2 classes menores. As principais classes usam o banco de dados (como muitas das minhas classes) e envia um email. Portanto, a classe principal tem um IPersonRepository
e um IEmailRepository
injetado, que por sua vez envia para as 2 classes menores.
Agora, quero testar a unidade principal na classe principal e aprendi a não unir o funcionamento interno da classe, porque devemos poder mudar o funcionamento interno sem interromper os testes de unidade.
Mas como a classe usa oe IPersonRepository
um IEmailRepository
, EU TENHO que especificar (simulação / simulação) resultados para alguns métodos para o IPersonRepository
. A classe principal calcula alguns dados com base nos dados existentes e os retorna. Se eu quiser testar isso, não vejo como posso escrever um teste sem especificar que o IPersonRepository.GetSavingsByCustomerId
retorno é x. Mas então meu teste de unidade 'sabe' sobre o funcionamento interno, porque 'sabe' quais métodos zombar e quais não.
Como posso testar uma classe que injetou dependências, sem o teste saber sobre os internos?
fundo:
Na minha experiência, muitos testes como esse criam simulações para os repositórios e, em seguida, fornecem os dados corretos para as simulações ou testam se um método específico foi chamado durante a execução. De qualquer forma, o teste conhece os internos.
Agora eu vi uma apresentação sobre a teoria (que eu ouvi antes) de que o teste não deveria saber sobre a implementação. Primeiro porque você não está testando como ele funciona, mas também porque, quando você altera a implementação, todos os testes de unidade falham porque eles 'sabem' sobre a implementação. Embora eu goste do conceito de que os testes desconhecem a implementação, não sei como realizá-la.
IPersonRepository
objeto, essa interface e todos os métodos descritos não são mais "internos", portanto, não é realmente um problema do teste. Sua verdadeira pergunta deve ser "como refatorar classes em unidades menores sem expor muito em público". A resposta é "mantenha essas interfaces enxutas" (aderindo ao princípio de segmentação de interfaces, por exemplo). Esse é o ponto 2 do IMHO na resposta de @ DavidArno (acho que não há necessidade de repetir isso em outra resposta).