Ambiente controlado para testes — Parte 1: Mockito e Injeção de dependência

Diego Gonçalves Santos
4 min readJan 17, 2019

--

Testes automatizados não te garantem que o software funciona em todos os cenários possíveis, mas te permitem assegurar que funcionam em cenários específicos definidos previamente. Instabilidades de rede e de serviços, respostas diferentes em requisições ao servidor, tudo isso dificulta muito a escrita dos testes. Existem algumas ferramentas que te ajudam a configurar esse ambiente controlado e previsível para que possamos validar os fluxos.

Independentemente de em qual plataforma você estiver implementando seus testes em algum momento se falará em mocks. Mocks são basicamente classes que substituem as utilizadas originalmente, para agir como dublês que agem de uma forma definida por nós. Mockito é uma das ferramentas mais conhecidas para criação de mocks no Android. Ela te permite criar classes “mockadas” e você pode definir quais respostas devem ser retornadas quando cada método desse mock é chamado e ainda verificar quais as interações feitas com aquela classe.

O uso da lib é muito simples. Apenas adicione a dependência ao seu projeto:

Mockito dependency

Se estiver usando Kotlin talvez você precise também do mockito inline pois em Kotlin todas as classes e funções são closed por default, portanto para criar mocks com o Mockito você precisará ou adicionar a palavra reservada open ao header de cada uma de suas classes, ou extrair interfaces delas para poder gerar o mock da interface. Mockito Inline resolve a questão e facilita bastante o processo.

Mockito inline dependency

Feito isso, usar o Mockito é muito simples! Você primeiro declara a sua classe “mockada”. Existem dois tipos de classes “mockadas” no Mockito. Você pode declarar ela usando a annotation @Mock como no exemplo abaixo e definir quais as respostas que o mock deve retornar a cada método chamado:

Mock

Ou usar a anotattion @Spy uma espécie de mock parcial, onde apenas os métodos que você decidir definir comportamentos serão sobrescritos, caso contrário o método original será executado.

Mock parcial

No seu método @Before na sua classe de teste você deve iniciar os Mocks e feito isso, basta em cada teste indicar quais resultados você gostaria que fossem retornados na chamada de cada método da classe “mockada”, ou verificar se um determinado método de uma classe mockada foi chamado.

Definindo comportamento de método e verificando interações

Apenas analisando rapidamente a sintaxe do código acima, basicamente chamamos o método when(), passando o nosso mock chamando o método que queremos sobrescrever como parâmetro. Como parâmetro para o método do mock, nesse caso passamos anyInt() e anyString() que basicamente não verificam o valor do parâmetro, apenas o tipo, se quiséssemos poderíamos definir um valor específico para o parâmetro e nesse caso, apenas se exatamente esse valor fosse passado na chamada do método do mock, aí sim essa resposta definida seria entregue. Essa funcionalidade é útil principalmente em casos que precisamos chamar mais de uma vez um mesmo método de um mock e precisamos que as respostas sejam diferentes. Em seguida chamamos o método thenReturn() e como parâmetro indicamos o que deve ser retornado quando alguma outra classe chamar esse método do mock.

Lendo em outras palavras essa linha de código: Quando alguém chamar o método “getList” do mock, passando qualquer inteiro como primeiro parâmetro e qualquer string como segundo parâmetro, então retorne o valor que esperamos.

Esta foi apenas uma breve introdução do que são mocks e como usar de forma básica o Mockito até para não se estender muito nesse artigo, mas para ver um pouco mais sobre Mockito, dêem uma olhada nesse artigo que é bem completo ou em sua documentação.

Um assunto no qual não vou entrar a fundo devido a sua complexidade e amplitude, mas que é importante lembrar quando se tratam de mocks, é que de nada adianta nós criarmos nossos mocks, se não tivermos uma forma de adicionar nossos mocks no lugar das classes “originais”. Ou seja, não importa qual o método que você utiliza para fazer suas injeções de dependências, mas é primordial que você tenha alguma ferramenta que te permita fazer isso. Nos exemplos desse artigo estou usando o Koin, uma ótima ferramenta de injeção de dependências para Kotlin. Com ela fica muito simples indicar que agora queremos que o mock seja utilizado para a nossa classe Repository:

Injetando mock com Koin

Pronto utilizando seus mocks, fica muito mais fácil testar suas classes em isolamento, pois você consegue ter previsibilidade dos retornos das outras classes e pode enfim testar apenas os pontos específicos que você precisar dadas as entradas definidas por você. Por hoje é isso! No próximo artigo da série vamos ver como mockar respostas de chamadas de serviço.

Até a próxima!

--

--

Diego Gonçalves Santos

Engenheiro de Software @Dextra_digital, escritor, palestrante, entusiasta de tecnologia e esportes.