Lendo alguns posts aqui do fórum, eu percebi que deveria começar a me preocupar mais com Unit Testing.
Trabalho em uma empresa pequena, onde tem apenas 2 programadores Java e outros PHP / Webdesigner, etc. Assim fica fácil fazer mudanças sem burocracia.
Ontem, eu e meu parceiro começamos a fazer alguns testes com JUnit + Mock object e realmente funcionaram como esperado.
Porém olhando o nosso código atual, existem vários métodos sem retorno (void), e são métodos importantes. Por exemplo:
NotaFiscal nota = new NotaFiscal();
nota.setClientes(clientes);
nota.setProdutos(produtos);
nota.efetuarCalculos(); //aqui está o método que eu quero testar
nota.imprimirNota();
Como podem ver no exemplo acima, eu tenho um método importante (efetuarCalculos()) que não tem retorno, na verdade ele pega os dados já definidos dentro do objeto nota, faz os calculos e armazena os valores dentro de atributos, que serão utilizados depois no método imprimirNota.
No caso acima, eu gostaria de testar o método efetuarCalculos sem usar o imprimirNota, porque o imprimirNota de fato, irá mandar dados para a impressora.
crie um método público get que retorne a/as variáveis. Ou mesmo substitua o toString da classe com os métodos em um encadeamento que você possa recuperar e avaliar o output
A verdadeira beleza dos testes começa a aparecer quando você se obriga a testar o seu código. Percebeu que é difícil de testá-lo?
Isso indica um pequeno problema na sua classe. Perceba que quem usa a classe precisa se lembrar de chamar efetuaCalculo() antes de imprimirNota(). O que acontece se ele esquecer? Problema?
O teste te indicou um problema de design, justamente pq está difícil de testar. No seu lugar eu refatorava e juntava os dois métodos em um só.
De forma alguma, a responsabilidade pode continuar sendo dividida entre os dois. O ruim é obrigar quem usa a chamar métodos a mais só para “configurar” o seu objeto.
Concordo com o Fabio. Uma parte muito legal dos testes é que comecamos a perceber dependencias muito grandes, metodos com muita responsabilidade, classes estranhas, etc…
Se voce assumir uma postura de test driven desgin (nao precisa nem ser xiita de digitar o teste antes, mas SEMPRE ir fazendo os testes paralelamente), vai perceber que suas classes ja vao nascer mais desacopladas…
Também concordo que no exemplo citado, o design da aplicação possa ser alterada para fazer mais sentido.
Porém, quebrando em vários métodos privates, como ficariam os testes? Um teste para o método “public” que internamente chama varios métodos privates, ou fazer um teste para cada método private? Se a segunda opçao for a correta, a melhor forma de testar um método private seria utilizando reflection entao?
Depende de cada caso Jair. Do jeito que está agora eu só testaria o método público. Mas se você perceber que os métodos privados estão com responsabilidades importantes e que é importante testá-los, refatora denovo , extrai o comportamento pra uma classe separada e testa a nova classe.
Show de bola Fábio, muito obrigado pelas dicas, alias, estou aprendendo bastante com esse tópico sobre JUnit.
Com essas e outras, começamos a notar como refatoramente é importante e necessário sempre.
Agora a pergunta do Marcos, acho que agora ficou claro para ele, como ele deve proceder , e eu daqui para frente irei prestar mais atenção na minha modelagem/implementação