Zombando de métodos particulares usando o PowerMock

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

Primeiro, vamos adicionar dependências necessárias para usar PowerMock com Mockito e JUnit em nossopom.xml:


    org.powermock
    powermock-module-junit4
    1.7.3
    test


    org.powermock
    powermock-api-mockito2
    1.7.3
    test

As versões mais recentes podem ser verificadashereehere.

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.