Mocking e Stubbing em testes de unidade

Introdução a Testes em Java

Maria Milusheva

Senior Software Engineer

Motivação: Dependências

Lembre o fluxo de dependências da lição anterior: o app de câmbio depende do servidor do banco: Um gráfico Mermaid do fluxo de dependências na demo bancária

Impossível verificar cálculos porque taxas de câmbio são inerentemente imprevisíveis.

Introdução a Testes em Java

Gerenciamento de dependências em testes

Mocking - criar objetos ou comportamentos simulados para objetos reais difíceis de usar em testes, permitindo testar sem depender de serviços externos.

Mockito - biblioteca Java poderosa para criar mocks.

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Exemplo de mocking

Introdução a Testes em Java

Mocking

  • Mock = como um dublê em uma peça, fingindo ser o objeto real apenas para o teste

Considere a lição anterior:

public double convertEuroTo(String currency, double amount) {
    double rate = this.bank.getRateEuroTo(currency);
    return amount * rate;
}

➡ Criar objeto previsível para EuropeanCentralBankServer nos testes

Introdução a Testes em Java

Mocking: câmbio de moedas

Como testamos com mocks:

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

// É preciso programar o mock para que funcione when(bank.getRateEuroTo("USD")).thenReturn(1.1);
// Chama getRateEuroTo no objeto mock, obtendo nossos valores pré-programados double result = exchangeApp.convertEuroTo("USD", 1000); assertEquals(1100, result); // Agora dá para verificar valores exatos }
Introdução a Testes em Java

Erro comum

Nunca esqueça de programar seus mocks:

@Test
void convert_returnsExpectedValue() {
    EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
    ExchangeApp exchangeApp = new ExchangeApp(bank);

    // Sem programação do mock - o objeto bank não sabe responder a getRateEuroTo
    double result = exchangeApp.convertEuroTo("USD", 1000);

    assertEquals(1100, result); // Vai falhar por falta de configuração do mock
}
Introdução a Testes em Java

Stubbing

O teste falha com:

org.opentest4j.AssertionFailedError: 
Expected :1100.0
Actual   :0.0

Programar um mock é chamado de stubbing.

Stubbing - fornecer respostas mínimas e pré-definidas às chamadas feitas durante o teste, geralmente não respondendo a nada além do que foi programado.

Introdução a Testes em Java

Exceções com Mockito

O Mockito também pode simular erros:

EuropeanCentralBankServer bank = mock(EuropeanCentralBankServer.class);
ExchangeApp exchangeApp = new ExchangeApp(bank);
// Em vez de thenReturn() use thenThrow()
when(bank.getRateEuroTo("USD"))
        .thenThrow(new RuntimeException("Bank server unavailable."));

exchangeApp.convertEuroTo("USD", 1000); // getRateEuroTo lançará exceção
Introdução a Testes em Java

Vamos praticar!

Introdução a Testes em Java

Preparing Video For Download...