Olá Pessoal,
O post de hoje veremos como usar Mockito para coberir classes e metodos DAO. Eu particularmente gosto de usar BDUnit para testes funcionais assim, mas há quem não gosta. Para não dizer que temos apenas uma solução resolvi escrever esse post.
Lets go..
Starting..
É comum achar que não é possível chamar o método real usando mock, mas analisando a documentação vamos encontrar um cara que permite chamar o método real, usando o mesmo contexto de mock,. Isso permite manter todo seu test com mock e ainda cobrir o que é de fato necessário.
No padrão de uso da mock, o código a seguir não rola cobertura, uma vez que estamos usando a mock, então o método real não é chamado:
@Test
public void testBuscaEmailCadastrado() {
user.setEmail(“camilo@”);
when(usuarioDaoMock.buscaUsuarioPorEmail(user)).thenReturn(user);
assertNotNull(usuarioDaoMock.buscaUsuarioPorEmail(user));
}
Como podemos ver na imagem acima, vermelho significa que não tem cobertura naquele código, uma vez que não há test case chamando ele direto.
E como resolver isso?
Para resolver é muito simples. Porém, antes de apresentar a solução vamos a outro fato tradicional, testar métodos do tipo void. Sabemos que com assert não é possível testar um método void, uma vez que este retorna “nada”. Mas com mock podemos chamar um método void e testá-lo, afetando assim a cobertura. Vejamos como:
O método doCallRealMethod() permite chamar o método real da mock, independente do tipo deste método. Sendo assim, void agora pode ser chamado e verificado no seu test case. É comum ver programadores tendo que converter um determinado método do tipo void para return alguma coisa só para satisfazer o test case. Sem o uso de mock (mockito) temos que fazer isso, porque não temos nenhum assert para verificar um tipo void que não retorna “nada”.
Observe na imagem a seguir o resultado, agora está cobrindo o DAO:
Note: segundo a documentação, o uso doCallRealMethod() é algo que deve ser feito cuidadosamente, pois significa que há algum tipo de complexidade no seu código, mas também não deixam de falar que há casos raros onde é possível usar the partial mock warning (é o nome que se dá quando chamamos um método real usando mock).
O code:
1 Mockito.doCallRealMethod().when(usuarioDaoMock).buscaUsuarioPorEmail(user);
2 assertEquals(usuarioDaoMock.buscaUsuarioPorEmail(user).getEmail(),user.getEmail());
A leitura do code: “chame o método real quando o método buscaUsuarioPorEmail for chamado pela usuariodaomock e passe o valor user para ele”.
Assim o mockito vai lá na classe que possui o método real e chama ele de fato, como vimos na imagem anterior, onde o código passa a ser coberto.
Um possível Problema
O único problema é que precisamos ter o banco de dados rodando, ou seja, UP para as funções que precisa consultar. Pode parecer óbvio, mas nem tanto, porque quando usamos a mock apenas, esta simula a chamada e o valor esperando independente do banco estar ON/OFF.
Resultado com o banco OFF é o seguinte:
org.hibernate.exception.JDBCConnectionException: Cannot open connection
Mas não esqueçam que ainda temos a vantagem de testar métodos do tipo void, fazendo a cobertura passar por ele. No contexto acima, na maioria das vezes vamos ter um BD ON, pois queremos ver se o nosso CRUD/DAO está fazendo o que de fato esperamos que ele faça, que é a comunicação com o BD, porém daí já estaríamos caminhando mais para tests funcionais que tests cases de fato.
Na imagem a seguir temos a cobertura em todo DAO. Observe que foi implementado um novo método que busca no banco um email e este não existe, daí verificamos se de fato o código entra no catch e este está coberto.
Cobertura antes
Cobertura depois
Mas, uma solução também é usar o banco em memoria como HSQLDB assim você poderá executar seus testes contra o banco automaticamente, ou seja, você não precisar iniciar ou parar o banco.
Vou ficando por aqui.
Abracos, see ya!!
Howdy! Eu sei que isso é meio estranho, mas eu estava pensando
Se você soubesse onde eu poderia localizar um plugin captcha para
Meu formulário de comentário? Estou usando a mesma plataforma de blog que a sua e estou tendo problemas para encontrar
1? Muito obrigado!