Testes Unitários na prática com Spring, TestNG, Mockito e Maven 2 : Parte 1
Neste post vou mostrar como podemos criar testes unitários para aplicações desenvolvidas com Spring usando o TestNG. Além disto usarei o framework para mocks chamado Mockito com isto será possível simular o comportamento de certos objetos para realizar o testes. No final vamos rodar estes testes com o Maven.
Se quiser saber mais sobre testes, Q.A e Maven sugiro que leia meus postas anteriores:
O testNG é um framework para testes unitários feito em Java para Java :). A solução é bem mais flexível do que o JUnit que é a solução mais tradicional de testes unitários em Java. O testNG prove mais facilidades do que o JUnit principalmente quando realizamos testes em grupos, esta funcionalidade eh útil para testar grupos de funcionalidades ou requisitos específicos.
Para uma comparação detalhada que vai de encontro a superioridade do testNG confira este link. Vou utilizar os recursos de integração do testNG com Spring. Vamos ver como injetar beans para testes e como utilizar o Mockito nos testes.
Mocks com o Mockito
Mockito é um excelente solução para mock objects. Por que além de muito simples, você trabalha com uma DSL muito focada e expressiva. O Mockito facilita muito a nossa vida por que podemos criar os mocks direto nos testes unitários evitado a necessidade de criar outras classes.
Claro que se necessário podemos criar classes para aproveitar os objetos mocks, podemos fazer isto usando o Spring e injetar uma classe cheia de mocks.
Estruturando os testes
Existem várias formas de estruturarmos os nossos testes unitários. Eu acredito que o melhor uso é quando temos um método para cada necessidade, como podemos realizar esta quebra? Das seguintes formas:
Tudo isso ajuda na hora de aplicar testes em cima de um conjunto de funcionalidades ou requisitos por exemplo na hora de fazer o deploy. Uma boa prática é rodar todos os testes sempre, a aplicação como um todo deve estar sempre funcionando, mas podemos criar uma certa rastreabilidade dos testes com os requisitos ou casos de uso.
Dependendo do projeto uma matriz de impacto ou rastreabilidade é suficiente, mas ter este mapeamento nos testes ajuda a acelerar as coisas.
Usando TestNG com Mockito
Quando criamos um teste unitário com o testNG é possível usar o Mockito para os objetos do teste e bem como para as dependências de sua aplicação. Desta maneira você consegue ter um isolamento total do seu código do resto da aplicação. Ainda é possível ter o seu código mesmo com dependências de outros pontos da aplicação que não estão prontos ainda.
Tudo junto na Prática
Vamos a uma aplicação de exemplo que fiz com todas estas soluções. A aplicação é fictícia serve para mostrar a integração desta solução como um todo e como usar o testNG com Spring e Mockito. Então sem mais delongas vamos a aplicação.
Vamos supor que estamos desenvolvendo uma solução de gestão de vendas de produtos para algum segmento do mercado. Então no nosso domínio fictício existem as seguintes entidade:
O Vendedor é o responsável pela Venda. Neste modelo poderíamos adicionar o Cliente, dados e entrega, forma de pagamento e muito mais, deixei o modelo restrito para facilitar o entendimento dos testes.
Por fim existe a Venda que contem uma lista de items e bem como um Vendedor. Você pode conferir isto no seguinte diagrama de classes a baixo:
Se quiser saber mais sobre testes, Q.A e Maven sugiro que leia meus postas anteriores:
- Testes do Desenvolvedor: Indo além do Debug
- Q.A Muito mais que Testes
- Integração Continua: O Verdadeiro Foco G.C ou Q.A?
- 10 Motivos para Você Usar Maven
- Maven 2.0.8 + Archiva 1.0.1 + Tomcat 6.0.16
- Mais Poder ao Maven com Archiva
O testNG é um framework para testes unitários feito em Java para Java :). A solução é bem mais flexível do que o JUnit que é a solução mais tradicional de testes unitários em Java. O testNG prove mais facilidades do que o JUnit principalmente quando realizamos testes em grupos, esta funcionalidade eh útil para testar grupos de funcionalidades ou requisitos específicos.
Para uma comparação detalhada que vai de encontro a superioridade do testNG confira este link. Vou utilizar os recursos de integração do testNG com Spring. Vamos ver como injetar beans para testes e como utilizar o Mockito nos testes.
Mocks com o Mockito
Mockito é um excelente solução para mock objects. Por que além de muito simples, você trabalha com uma DSL muito focada e expressiva. O Mockito facilita muito a nossa vida por que podemos criar os mocks direto nos testes unitários evitado a necessidade de criar outras classes.
Claro que se necessário podemos criar classes para aproveitar os objetos mocks, podemos fazer isto usando o Spring e injetar uma classe cheia de mocks.
Estruturando os testes
Existem várias formas de estruturarmos os nossos testes unitários. Eu acredito que o melhor uso é quando temos um método para cada necessidade, como podemos realizar esta quebra? Das seguintes formas:
- Um método por cenário, para que usa casos de uso.
- Um método por feature, para quem usa FDD por exemplo.
- Vários métodos por requisitos, no caso de uma metodologia tradicional como o RUP.
- Os método são criados conforme o caso de teste do Analista de Testes, um por cenário.
Tudo isso ajuda na hora de aplicar testes em cima de um conjunto de funcionalidades ou requisitos por exemplo na hora de fazer o deploy. Uma boa prática é rodar todos os testes sempre, a aplicação como um todo deve estar sempre funcionando, mas podemos criar uma certa rastreabilidade dos testes com os requisitos ou casos de uso.
Dependendo do projeto uma matriz de impacto ou rastreabilidade é suficiente, mas ter este mapeamento nos testes ajuda a acelerar as coisas.
Usando TestNG com Mockito
Quando criamos um teste unitário com o testNG é possível usar o Mockito para os objetos do teste e bem como para as dependências de sua aplicação. Desta maneira você consegue ter um isolamento total do seu código do resto da aplicação. Ainda é possível ter o seu código mesmo com dependências de outros pontos da aplicação que não estão prontos ainda.
Tudo junto na Prática
Vamos a uma aplicação de exemplo que fiz com todas estas soluções. A aplicação é fictícia serve para mostrar a integração desta solução como um todo e como usar o testNG com Spring e Mockito. Então sem mais delongas vamos a aplicação.
Vamos supor que estamos desenvolvendo uma solução de gestão de vendas de produtos para algum segmento do mercado. Então no nosso domínio fictício existem as seguintes entidade:
- Produto
- Item
- Vendedor
- Venda
- Comissao
O Vendedor é o responsável pela Venda. Neste modelo poderíamos adicionar o Cliente, dados e entrega, forma de pagamento e muito mais, deixei o modelo restrito para facilitar o entendimento dos testes.
Por fim existe a Venda que contem uma lista de items e bem como um Vendedor. Você pode conferir isto no seguinte diagrama de classes a baixo:
Diagrama de classes do modelo
Certo agora vamos aos serviços da aplicação. Esta aplicação poderia ter vários serviços, por motivos de simplificação e foco do post vou usar apénas 2 serviços sendo que um deles não foi implementado ainda, então vamos aos serviços e as suas implementações:
- ItemService
- VendaService -> VendaServiceImpl
Diagrama de classes dos Serviços
Podemos trabalhar com dois cenários. Imagine que você desenvolveu o serviço de vendas ou tem que desenvolver o mesmo e o serviço de items não esta pronto ainda. É possível tocar este desenvolvimento em paralelo, isto é feito através do contrato dos serviços(interfaces) e ainda é possível testar seu código mesmo sem o serviço de item estar pronto para isso vamos usar o TestNG com o Mockito.
Em um segundo cenário o serviço de items está pronto, mas a sua implementação foi feita por outra pessoa e é muito duvidosa, logo você pode ter certeza que o seu código esta ok ou se o problema é no serviço de items, logo você também poderia usar o Mockito com o TestNG para isolar a aplicação e testar somente esta parte.
No próximo post vou mostrar os códigos desta aplicação além de discutir mais sobre teste unitários, Spring e Mockito. Você pode baixar os diagramas que fiz no EA neste url.
Abraços e até a próxima.
Em um segundo cenário o serviço de items está pronto, mas a sua implementação foi feita por outra pessoa e é muito duvidosa, logo você pode ter certeza que o seu código esta ok ou se o problema é no serviço de items, logo você também poderia usar o Mockito com o TestNG para isolar a aplicação e testar somente esta parte.
No próximo post vou mostrar os códigos desta aplicação além de discutir mais sobre teste unitários, Spring e Mockito. Você pode baixar os diagramas que fiz no EA neste url.
Abraços e até a próxima.