Zombando de métodos particulares usando o PowerMock
1. Visão geral
Um dos desafios do teste de unidade é zombar de métodos privados.
Neste tutorial, aprenderemos como podemos conseguir isso usando a bibliotecaPowerMock - que é compatível com JUnit e TestNG.
PowerMock integrates with mocking frameworks like EasyMock and Mockito and is meant to add additional functionality to these – such as mocking private methods, final classes, and final methods, etc.
Isso é feito com a manipulação de bytecode e um carregador de classes totalmente separado.
2. Dependências do Maven
3. Exemplo
Vamos começar com um exemplo deLuckyNumberGenerator. Esta classe tem um único método público para gerar um número da sorte:
public int getLuckyNumber(String name) {
saveIntoDatabase(name);
if (name == null) {
return getDefaultLuckyNumber();
}
return getComputedLuckyNumber(name.length());
}
4. Variações na simulação de métodos privados
Para testes de unidade exaustivos do método, precisaríamos simular métodos privados.
4.1. Método sem argumentos, mas com valor de retorno
Como um exemplo simples, vamos simular o comportamento de um método privado sem argumentos e forçá-lo a retornar o valor desejado:
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
when(mock, "getDefaultLuckyNumber").thenReturn(300);
Nesse caso, simulamos o método privadogetDefaultLuckyNumbere fazemos com que ele retorne um valor de 300.
4.2. Método com argumento e valor de retorno
A seguir, vamos simular o comportamento de um método privado com um argumento e forçá-lo a retornar o valor desejado:
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
doReturn(1).when(mock, "getComputedLuckyNumber", ArgumentMatchers.anyInt());
Nesse caso, zombamos do método privado e o fazemos retornar 1.
Observe que não nos importamos com o argumento de entrada e usamosArgumentMatchers.anyInt() como curinga.
4.3. Verificação de invocação de um método
Nossa estratégia final é usar o PowerMock para verificar a invocação de um método privado:
LuckyNumberGenerator mock = spy(new LuckyNumberGenerator());
int result = mock.getLuckyNumber("Tyranosorous");
verifyPrivate(mock).invoke("saveIntoDatabase", ArgumentMatchers.anyString());
5. Uma palavra de cautela
Finalmente, embora os métodos privados possam ser testados usando PowerMock,we must be extra cautious while using this technique.
Dada a intenção de nossos testes é validar o comportamento de uma classe, devemos evitar alterar o comportamento interno da classe durante o teste de unidade.
As técnicas de mocking devem ser aplicadas às dependências externas da classe e não à própria classe.
Se a imitação de métodos privados é essencial para testar nossas classes, geralmente indica um design incorreto.
6. Conclusão
Neste artigo rápido, mostramos como o PowerMock pode ser usado para estender a capacidade do Mockito para zombar e verificar métodos privados na classe em teste.
O código-fonte deste tutorial pode ser encontradoover on GitHub.