Testando seu código Java com o Mockito framework

Silas Candiolli
CWI Software
Published in
4 min readNov 12, 2020
Engadget

Utilizo o Mockito faz alguns anos, e considero uma ferramenta muito poderosa. Eu vejo que seria muito complicado criar testes sem ele. Mas nem sempre foi facil utiliza-lo, não por causa do Mockito, mas sim por minha causa. Pois pensar orientado a testes é dificil no começo.

De forma prática, quero trazer exemplos de utilização do Mockito em casos reais do meu dia a dia, e mostrar como ele pode nos ajudar a testar codigo complexos.

O que é o Mockito?

O Mockito é um framework de testes unitários e o seu principal objetivo é instanciar classes e controlar o comportamento dos métodos. Isso é chamado de mock, na tradução livre quer dizer zombar, e talvez seja mesmo o termo que melhor o define. Pois ao mockar a dependencia de uma classe, eu faço com que a classe que estou testando pense estar invocando o metodo realmente, mas de fato não está. Conforme o desenho abaixo tenta explicar.

Fluxo quando chamar o metodo mockado

Configurando

A instalação do Mockito no seu projeto é muito simples, assim como sua utilização. Seguindo o how to do site é bem facil de fazer.

Após o Mockito estar nas dependencias do seu projeto, ja é possível anotar suas classes e criar mocks. E ai você tem algumas formas de testar seus metodos, que podem variar conforme a sua implementação.

Para os exemplos a seguir utilizei as seguintes bibliotecas:

  • Java 11
  • Mockito 4.7.0
  • JUnit 4.13.2

Resumo

  • Mock: cria uma instancia de uma classe, porém Mockada. Se você chamar um metodo ele não irá chamar o metodo real, a não ser que você queira.
  • Spy: cria uma instancia de uma classe, que você pode mockar ou chamar os metodos reais. É uma alternativa ao InjectMocks, quando é preciso mockar metodos da propria classe que esta sendo testada.
  • InjectMocks: criar uma intancia e injeta as dependências necessárias que estão anotadas com @Mock.
  • Verify: verifica a quantidade de vezes e quais parametros utilizados para acessar um determinado metodo.
  • When: Após um mock ser criado, você pode direcionar um retorno para um metodo dado um paremetro de entrada.
  • Given: Mesmo propósito que o when, porém é utilizado para BDD. Fazendo parte do BDDMockito.

Praticando

Nesse ponto quero desmostrar a utilização do Mock/@Mock. Com esse metodo, é possível instanciar uma classe dependente da classe que voce esta testando, e mockar seus metodos. Isso é importante para, testar a unidade. Pois conseguimos isolar o comportamento de um metodo, por isso são chamados de testes unitários.

Quando criamos testes é possível perceber o quão complexo ficou nosso código. Geralmente, se existes muitas dependencias em uma classe, significa que ela poderia ser quebrada em mais de uma. O mesmo vale para os metodos.

A divisão de camadas e pacotes de um software existe para diminuir o acoplamento e manter a coesão, fazendo com que as classes e metodos tenham uma unica responsabilidade. Isso torna a leitura e manutenção do código mais simples.

1. Mock | When

Nesse exemplo abaixo, criei um mock() da classe CustomerRegister para testar o comportamento do metodo validateRealCpf . Evidentemente, eu terei um resultado positivo, independente do valor que eu passar para ser validado. Isso ocorre porque eu utilizei o when().

Agora, se eu chamar o metodo real, utilizando o thenCallRealMethod() do Mockito, o teste falha. Porque o CPF informado é inválido, e o meu teste passou pelo metodo validateRealCpf() de fato.

2. InjectMocks

Eu posso usar o mock() em outros contextos pouco mais complexos, como para obter um resultado positivo do repository.save(), independente do que este receba como parametro de entrada. No exemplo abaixo utilizei as anotações @InjectMocks, @Mock e @BeforeEach conforme codigo abaixo:

3. Spy

No exemplo seguinte, farei um teste utilizando a função Spy()/@Spy, que possibilita mockar a classe que está sendo testada. Algo que você não consegue fazer utilizando somente o @InjectMocks. Vejamos o exemplo abaixo:

3. Verify

No exemplo abaixo, vou explorar alguns casos de uso do verify().

É possível fazer verificar por quantidade de interação:

verify(customerRegister, times(1)).register(vo);

Verificar quando não houver interação:

verifyNoInteractions(repository);

Verificar quando não houver outras interações além das que eu ja verifiquei, utilizar o verifyNoMoreInteractions(), por exemplo:

Conclusão

Para concluir, eu gostaria de ressaltar a importancia desse framework para o nosso dia a dia. Todos sabemos que é necessário testar, e o Mockito é uma ótima ferramenta para isso, pois é a possibilidade de isolar comportamentos e testar pequenas partes é uma grande estratégia para garantir a qualidade.

O projeto utilizado nesse artigo esta no GitHub. Qualquer dúvida e feedback sobre o artigo, estou a disposição.

Referências

--

--