Tag Archives: boas práticas

Testes e infraestrutura: inimigos de longa data

TL;DR: Suas classes com regras de negócio não podem depender de infraestrutura. Elas devem ser facilmente testáveis por meio de testes de unidade. Dependências devem ter interfaces amigáveis e serem facilmente mockadas.

Às vezes ouço perguntas como “como testo meu sistema em Android”, ou “como testo meu sistema em JSF”, ou “como testo meu sistema em <ponha-sua-tecnologia-aqui>”. Pra mim, essa pergunta faz todo sentido se você está procurando uma maneira de fazer testes de sistema. Algo como Selenium, só que Android. No entanto, se você está pensando em testes de unidade, essa pergunta não deveria ser muito importante.

Regras de negócio são importantes. Tão importantes que merecem ficar o mais afastado possível da sua infraestrutura. Ou seja, não importa se você usa JSF, Android, ou whatever, o coração do sistema deve ficar em classes Java, simples, que não dependem de nada externo. Se você pensar sempre assim, pronto, todas suas regras de negócio serão facilmente testadas.

Ah, mas e se pra realizar aquela regra de negócios, eu precisar consultar uma infraestrutura? Sei lá, pegar um dado do banco de dados, ou postar algo em um serviço web? Faça sua classe depender de uma classe que tenha uma interface bastante amigável. Algo como bd.pegaValor() ou correios.calcula(“SP”). Nada que você tenha que ficar escrevendo linhas e linhas para chegar no resultado que espera. Assim, fica fácil mockar depois para testar. E dentro da dependência, você faz o que tiver que fazer pra fazer a infraestrutura funcionar.

Se você pensar assim sempre, a infraestrutura que está usando deixa de ser importante. Afinal, você fugiu dela. E testou o que precisava ser testado.

Como você usa construtores?

Construtores são legais, afinal, eles nos permitem garantir que uma classe não será instanciada sem alguns dados básicos. No entanto, a dúvida sempre aparece: o que devemos passar pelo construtor e o que devemos passar pelo método?

Bem, minhas regras pessoais são:

  • Se a classe é uma entidade, então eu peço no construtor todos os dados necessários para que a entidade seja válida. Por exemplo, Pessoa precisa de nome, vai pelo construtor.
  • Se a classe não é uma entidade, e ela precisa de “ferramentas de trabalho” (outras dependências, como DAOs, etc), eu as passo todas pelo construtor, sempre. Já os valores que serão utilizados ao longo do processamento, eu passo sempre pelo método.
  • Se algum dos frameworks que estou usando me obrigar a ter um construtor default, eu o crio, com a menor visibilidade possível, e o anoto com @Deprecated.
  • Se estou refatorando algum código legado, não me incomodo de ter um construtor padrão, fazendo alguma ação padrão.
  • Se minha classe aceita diferentes combinações de valores obrigatórios, tenho diferentes construtores. Em entidades, se tenho atributos não obrigatórios, às vezes crio dois construtores, recebendo e não recebendo aquele atributo. Depende da situação.

Acho que é isso. Se vc tiver as suas regras, estou curioso para conhecê-las!