Como não tenho muita experiência em testes de unidade, estou tentando reunir algumas regras que aprenderei primeiro.
Tenha cuidado ao aprender "regras" para problemas que você nunca encontrou. Se você se deparar com alguma "regra" ou "melhor prática", sugiro encontrar um exemplo simples de brinquedo onde essa regra "deve" ser usada e tentar resolver esse problema sozinho , ignorando o que a "regra" diz.
Nesse caso, você pode tentar criar 2 ou 3 classes simples e alguns comportamentos que eles devem implementar. Implemente as classes da maneira que parecer natural e escreva um teste de unidade para cada comportamento. Faça uma lista de todos os problemas que você encontrou, por exemplo, se você começou com as coisas funcionando de uma maneira, teve que voltar e mudar mais tarde; se você ficou confuso sobre como as coisas devem se encaixar; se você se aborreceu ao escrever clichê; etc.
Em seguida, tente resolver o mesmo problema seguindo a "regra". Mais uma vez, faça uma lista dos problemas que encontrou. Compare as listas e pense em quais situações podem ser melhores ao seguir a regra e quais não.
Quanto à sua pergunta real, eu tendem a favorecer uma abordagem de portas e adaptadores , onde fazemos uma distinção entre "lógica principal" e "serviços" (isso é semelhante à distinção entre funções puras e procedimentos eficazes).
A lógica principal é calcular as coisas "dentro" do aplicativo, com base no domínio do problema. Ela pode conter classes como User
, Document
, Order
, Invoice
, do etc. É bom ter classes principais chamar new
para outras classes principais, já que eles são detalhes "internas" de implementação. Por exemplo, criar um Order
também pode criar um Invoice
e um Document
detalhamento do que foi solicitado. Não é necessário zombar deles durante os testes, porque essas são as coisas reais que queremos testar!
As portas e os adaptadores são como a lógica principal interage com o mundo externo. Isto é onde as coisas como Database
, ConfigFile
, EmailSender
, etc. viver. Essas são as coisas que dificultam o teste; portanto, é aconselhável criá-las fora da lógica principal e transmiti-las conforme necessário (com injeção de dependência ou como argumentos de método etc.).
Dessa forma, a lógica principal (que é a parte específica do aplicativo, onde a importante lógica de negócios vive e está sujeita à maior rotatividade) pode ser testada sozinha, sem a necessidade de se preocupar com bancos de dados, arquivos, emails, etc. Podemos apenas passar alguns valores de exemplo e verificar se obtemos os valores de saída corretos.
As portas e os adaptadores podem ser testados separadamente, usando simulações para o banco de dados, sistema de arquivos, etc. sem precisar se preocupar com a lógica de negócios. Podemos apenas passar alguns valores de exemplo e garantir que eles estejam sendo armazenados / lidos / enviados / etc. adequadamente.