Mockito é um framework de código aberto para criar objetos mock em testes unitários Java e Kotlin, que permite isolar o código testado das dependências externas. Com sua ajuda, o desenvolvedor substitui repositórios reais, clientes API e bancos de dados por stubs controlados com comportamento predefinido. De acordo com Mockito.org, a biblioteca é usada em mais de 60% dos projetos Java que utilizam testes unitários.
Pontos principais
Mockito é uma biblioteca de código aberto para criar objetos mock (stubs) em testes unitários para Java, Kotlin e outras linguagens JVM. Ao contrário do JUnit, que é responsável pela execução dos testes, o Mockito resolve o problema de isolamento — substitui as dependências reais da classe testada por objetos previsíveis.
Sem mocks, testar um método que acessa um banco de dados ou API externa requer a configuração de um ambiente real — implantar um banco de dados, iniciar um servidor. O Mockito substitui essas dependências por objetos com comportamento fixo: o método repository.findById(1) sempre retorna um objeto User específico sem acessar o banco de dados.
A arquitetura do Mockito é baseada no padrão Proxy (para interfaces e classes). A biblioteca gera uma subclasse ou proxy para o tipo especificado e intercepta todas as chamadas de métodos, retornando valores padrão ou valores definidos via when().thenReturn().
O princípio de funcionamento do Mockito é construído em três operações básicas: criação do mock, configuração do comportamento (stubbing) e verificação de chamadas (verification). Cada operação usa métodos estáticos da classe org.mockito.Mockito — a classe mais baixada no ecossistema Java de acordo com as estatísticas do Maven Central. Todas as chamadas de métodos do mock são registradas na memória, permitindo verificação posterior através do verify.
Um teste típico com Mockito consiste em três fases: Arrange — criação de mocks e configuração de stubs via when().thenReturn(), Act — chamada do método testado, Assert — verificação do resultado via assertEquals e verify(mock). Essa abordagem é chamada AAA (Arrange-Act-Assert).
Vamos ver um teste simples onde o Mockito substitui um repositório de usuários. O método when().thenReturn() configura o mock para que a chamada findById retorne um objeto User previamente preparado.
// Criando um mock de repositório
UserRepository mockRepo = mock(UserRepository.class);
// Configurando o comportamento: findById(1) retorna um usuário
when(mockRepo.findById(1)).thenReturn(new User("Alice"));
// Verificando que o método foi realmente chamado
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);
Mockito fornece duas maneiras de criar mocks: o método estático mock(Class) e a anotação @Mock com inicialização via MockitoAnnotations.openMocks(). A primeira abordagem é compacta para um ou dois mocks, a segunda é conveniente quando há muitas dependências — as anotações reduzem o código boilerplate.
O método mock() recebe uma classe e retorna um objeto stub que pode ser configurado via when().thenReturn(). Todos os métodos não configurados retornam valores padrão: 0 para números, false para boolean, null para objetos.
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);
A anotação @Mock combinada com @ExtendWith(MockitoExtension.class) cria automaticamente mocks para todos os campos da classe de teste. O MockitoExtension é responsável pela inicialização antes de cada teste.
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void getUserShouldReturnUserFromRepo() {
when(userRepository.findById(1)).thenReturn(new User("Alice"));
User result = userService.getUser(1);
assertEquals("Alice", result.getName());
}
}
Stubbing é o processo de definir o que um método do mock deve retornar quando chamado com argumentos específicos. A sintaxe básica: when(mock.method(args)).thenReturn(value). Para diferentes cenários, o Mockito oferece várias variantes de métodos then.
| Método | Propósito |
|---|---|
| thenReturn(value) | Sempre retorna o valor especificado |
| thenThrow(exception) | Lança uma exceção quando chamado |
| thenAnswer(answer) | Calcula o valor de retorno dinamicamente |
| thenCallRealMethod() | Chama o método real (mock parcial) |
Quando o valor de retorno depende dos argumentos da chamada, usa-se thenAnswer com uma lambda. Isso é útil para simular trabalho com dados reais — por exemplo, gerar um ID com base no objeto recebido.
when(repository.save(any())).thenAnswer(invocation -> {
User user = invocation.getArgument(0);
user.setId(42);
return user;
});
Verify é um recurso único do Mockito que bibliotecas de objetos mock mais antigas (EasyMock, jMock) não fornecem.
O Verify torna os testes mais confiáveis porque verifica não apenas o valor de retorno, mas também os efeitos colaterais — chamadas a métodos que não retornam resultado (métodos void). O método verify(mock).methodName(args) verifica se um método específico do mock foi chamado com os argumentos indicados. Isso permite testar não apenas o resultado, mas também o processo — o fato de acessar a dependência.
Por padrão, o verify verifica que o método foi chamado exatamente uma vez. Se um número diferente for necessário, usa-se times(n), atLeast(n), never() e outros modificadores da classe Mockito.
// Verificação do número de chamadas
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);
// Verificação da ordem das chamadas
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();
Quando é necessário verificar com qual objeto exato um método foi chamado, usa-se ArgumentCaptor. Ele captura o valor do argumento durante a chamada e permite verificar seus campos individualmente. O ArgumentCaptor é especialmente útil quando o código testado cria um objeto internamente e o passa para uma dependência — você não pode verificar esse objeto de outra forma.
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());
@Mock e @InjectMocks são duas anotações chave do Mockito que reduzem significativamente o código boilerplate. @Mock cria um mock para um campo, e @InjectMocks injeta todos os mocks da classe de teste no objeto testado através de construtor, setter ou campo.
O mecanismo de @InjectMocks tenta injetar as dependências na seguinte ordem: construtor com o maior número de argumentos, setter por tipo, campo privado. Se nenhum desses métodos funcionar, o objeto permanece com dependências null e o teste falhará com uma NullPointerException.
É importante entender: @InjectMocks não analisa os tipos dos campos — ele substitui qualquer mock compatível por tipo. Se uma classe tem dois campos do mesmo tipo, o Mockito pode injetar o mock errado. Nesses casos, recomenda-se usar um construtor explícito com parâmetros mock.
No desenvolvimento Android, o Mockito é usado junto com o JUnit para testar ViewModel, Repository e UseCase. Como essas classes são executadas na JVM sem o contexto Android, o Mockito substitui suas dependências — Room DAO, Retrofit API, SharedPreferences — por stubs com comportamento previsível.
Para adicionar Mockito a um projeto Android, basta adicionar a dependência mockito-core ou mockito-inline (esta última suporta mocking de classes finais e métodos estáticos). A versão 5.12.0 (2024) inclui suporte para Java 21 e integração melhorada com JUnit 5.
// build.gradle.kts (module)
dependencies {
testImplementation("org.mockito:mockito-core:5.12.0")
testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}
Anteriormente, para mockar métodos estáticos e construtores era necessário PowerMock — uma extensão que funcionava através de instrumentação de bytecode. A partir do Mockito 5.x com mockito-inline, essa capacidade está integrada diretamente: mockStatic(ClassName.class) permite mockar métodos estáticos sem bibliotecas adicionais.
Um cenário típico: um ViewModel chama um método do repositório e transforma o resultado em estado de UI. O Mockito substitui o repositório, e o teste verifica se o ViewManager lida corretamente tanto com a resposta de sucesso quanto com o erro. Ao usar a Clean Architecture, mocks são criados para cada camada: DataSource, Repository e UseCase — isso permite testar cada camada isoladamente.
Perguntas frequentes
Mockito é uma biblioteca para Java e Kotlin que usa proxies e reflexão. MockK é uma biblioteca Kotlin-first com suporte para corrotinas, funções de extensão e classes finais sem configuração adicional.
A partir do Mockito 2.1, o mocking de classes finais é suportado via opt-in. Na versão 5.x (mockito-inline), isso está ativado por padrão. Basta adicionar a dependência mockito-inline e usar o método mock() padrão.
Um Spy é um mock parcial que por padrão chama métodos reais, mas permite sobrescrever alguns deles via when().thenReturn(). Spy é útil para testar código legado quando não é possível reescrever a classe inteira.
thenReturn sempre retorna o mesmo valor, independentemente dos argumentos. thenAnswer calcula o valor de retorno com base na invocação — argumentos da chamada, o próprio mock e o estado. Para respostas dinâmicas, use sempre thenAnswer.
Verify verifica não apenas o resultado, mas também o processo — o fato de acessar a dependência. Isso é crítico para serviços que precisam salvar dados ou enviar notificações. Sem verify, o teste não detectará que um método não chamou save() ou send().
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também