Mockito — cos’è, concetti chiave e principio di funzionamento

Autore: IT Sectr Pubblicato: 2026-04-08 Tempo di lettura: 8 min

Mockito è un framework open source per creare oggetti mock nei test unitari Java e Kotlin, che consente di isolare il codice testato dalle dipendenze esterne. Con il suo aiuto, lo sviluppatore sostituisce repository reali, client API e database con stub controllati dal comportamento predefinito. Secondo Mockito.org, la libreria è utilizzata in oltre il 60% dei progetti Java che utilizzano test unitari.

Punti chiave

  • Mockito — una libreria per creare oggetti mock che sostituiscono dipendenze reali nei test.
  • Mock — un oggetto stub che simula il comportamento di un componente reale.
  • Stubbing — configurazione del valore restituito quando si chiama un metodo del mock.
  • Verify — verifica che un metodo sia stato chiamato con argomenti specifici.
  • @InjectMocks — iniezione automatica delle dipendenze mock nell’oggetto testato.

Cos’è Mockito?

Mockito è una libreria open source per creare oggetti mock (stub) nei test unitari per Java, Kotlin e altri linguaggi JVM. A differenza di JUnit, che si occupa dell’esecuzione dei test, Mockito risolve il problema dell’isolamento — sostituisce le dipendenze reali della classe testata con oggetti prevedibili.

Senza mock, testare un metodo che accede a un database o a un’API esterna richiede la configurazione di un ambiente reale — distribuzione di un database, avvio di un server. Mockito sostituisce queste dipendenze con oggetti dal comportamento fisso: il metodo repository.findById(1) restituisce sempre un oggetto User specifico senza accedere al database.

L’architettura di Mockito si basa sul pattern Proxy (per interfacce e classi). La libreria genera una sottoclasse o un proxy per il tipo specificato e intercetta tutte le chiamate ai metodi, restituendo valori predefiniti o valori impostati tramite when().thenReturn().

Come funziona Mockito

Il principio di funzionamento di Mockito si basa su tre operazioni fondamentali: creazione del mock, configurazione del comportamento (stubbing) e verifica delle chiamate (verification). Ogni operazione utilizza metodi statici della classe org.mockito.Mockito — la classe più scaricata nell’ecosistema Java secondo le statistiche di Maven Central. Tutte le chiamate ai metodi del mock vengono registrate in memoria, consentendo la successiva verifica tramite verify.

Tre fasi di un test con Mockito

Un test tipico con Mockito si compone di tre fasi: Arrange — creazione dei mock e configurazione degli stub tramite when().thenReturn(), Act — chiamata al metodo testato, Assert — verifica del risultato tramite assertEquals e verify(mock). Questo approccio è chiamato AAA (Arrange-Act-Assert).

Esempio base con un mock del repository

Consideriamo un test semplice in cui Mockito sostituisce un repository di utenti. Il metodo when().thenReturn() configura il mock in modo che la chiamata findById restituisca un oggetto User preparato in precedenza.

java
// Creazione di un mock del repository
UserRepository mockRepo = mock(UserRepository.class);

// Configurazione del comportamento: findById(1) restituisce un utente
when(mockRepo.findById(1)).thenReturn(new User("Alice"));

// Verifica che il metodo sia stato effettivamente chiamato
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);

Creazione di oggetti mock

Mockito fornisce due modi per creare mock: il metodo statico mock(Class) e l’annotazione @Mock con inizializzazione tramite MockitoAnnotations.openMocks(). Il primo approccio è compatto per uno o due mock, il secondo è comodo quando ci sono molte dipendenze — le annotazioni riducono il codice boilerplate.

Tramite il metodo statico mock()

Il metodo mock() accetta una classe e restituisce un oggetto stub che può essere configurato tramite when().thenReturn(). Tutti i metodi non configurati restituiscono valori predefiniti: 0 per i numeri, false per boolean, null per gli oggetti.

java
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);

Tramite l’annotazione @Mock con JUnit 5

L’annotazione @Mock combinata con @ExtendWith(MockitoExtension.class) crea automaticamente mock per tutti i campi della classe di test. MockitoExtension si occupa dell’inizializzazione prima di ogni test.

java
@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: configurazione del comportamento del mock

Stubbing è il processo di definizione di ciò che un metodo del mock deve restituire quando chiamato con argomenti specifici. La sintassi di base: when(mock.method(args)).thenReturn(value). Per diversi scenari, Mockito offre varie varianti di metodi then.

MetodoScopo
thenReturn(value)Restituisce sempre il valore specificato
thenThrow(exception)Lancia un’eccezione quando chiamato
thenAnswer(answer)Calcola il valore restituito dinamicamente
thenCallRealMethod()Chiama il metodo reale (mock parziale)

Risposta dinamica tramite thenAnswer

Quando il valore restituito dipende dagli argomenti della chiamata, si usa thenAnswer con una lambda. Ciò è utile per simulare il lavoro con dati reali — ad esempio, generare un ID basato sull’oggetto ricevuto.

java
when(repository.save(any())).thenAnswer(invocation -> {
    User user = invocation.getArgument(0);
    user.setId(42);
    return user;
});

Verify: verifica delle interazioni con il mock

Verify è una funzionalità unica di Mockito che le librerie di oggetti mock più datate (EasyMock, jMock) non forniscono.

Verify rende i test più affidabili perché verifica non solo il valore restituito ma anche gli effetti collaterali — chiamate a metodi che non restituiscono risultato (metodi void). Il metodo verify(mock).methodName(args) verifica se un metodo specifico del mock è stato chiamato con gli argomenti indicati. Ciò consente di testare non solo il risultato ma anche il processo — il fatto di accedere alla dipendenza.

Verifica del numero di chiamate

Per impostazione predefinita, verify controlla che il metodo sia stato chiamato esattamente una volta. Se è necessario un numero diverso, si usano times(n), atLeast(n), never() e altri modificatori della classe Mockito.

java
// Verifica del numero di chiamate
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);

// Verifica dell’ordine delle chiamate
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();

ArgumentCaptor per catturare gli argomenti

Quando è necessario verificare con quale oggetto esatto è stato chiamato un metodo, si usa ArgumentCaptor. Cattura il valore dell’argomento durante la chiamata e consente di verificare i suoi campi singolarmente. ArgumentCaptor è particolarmente utile quando il codice testato crea un oggetto internamente e lo passa a una dipendenza — non è possibile verificare quell’oggetto altrimenti.

java
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());

Annotazioni @Mock e @InjectMocks

@Mock e @InjectMocks sono due annotazioni chiave di Mockito che riducono significativamente il codice boilerplate. @Mock crea un mock per un campo, e @InjectMocks inietta tutti i mock della classe di test nell’oggetto testato tramite costruttore, setter o campo.

Il meccanismo di @InjectMocks tenta di iniettare le dipendenze nel seguente ordine: costruttore con il maggior numero di argomenti, setter per tipo, campo privato. Se nessuno di questi metodi funziona, l’oggetto rimane con dipendenze null e il test fallirà con una NullPointerException.

Regole per l’uso di @InjectMocks

È importante capire: @InjectMocks non analizza i tipi dei campi — sostituisce qualsiasi mock compatibile per tipo. Se una classe ha due campi dello stesso tipo, Mockito potrebbe iniettare il mock sbagliato. In tali casi, si consiglia di utilizzare un costruttore esplicito con parametri mock.

Mockito nei progetti Android

Nello sviluppo Android, Mockito viene utilizzato insieme a JUnit per testare ViewModel, Repository e UseCase. Poiché queste classi vengono eseguite sulla JVM senza il contesto Android, Mockito sostituisce le loro dipendenze — Room DAO, Retrofit API, SharedPreferences — con stub dal comportamento prevedibile.

Configurazione Gradle per Mockito

Per aggiungere Mockito a un progetto Android, basta aggiungere la dipendenza mockito-core o mockito-inline (quest’ultima supporta il mocking di classi final e metodi statici). La versione 5.12.0 (2024) include il supporto per Java 21 e un’integrazione migliorata con JUnit 5.

kotlin
// build.gradle.kts (module)
dependencies {
    testImplementation("org.mockito:mockito-core:5.12.0")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}

Mockito e PowerMock: pratica obsoleta

In precedenza, per mockare metodi statici e costruttori era necessario PowerMock — un’estensione che funzionava tramite strumentazione del bytecode. A partire da Mockito 5.x con mockito-inline, questa funzionalità è integrata direttamente: mockStatic(ClassName.class) consente di mockare metodi statici senza librerie aggiuntive.

Test del ViewModel con Mockito

Uno scenario tipico: un ViewModel chiama un metodo del repository e trasforma il risultato in stato UI. Mockito sostituisce il repository e il test verifica che il ViewModel gestisca correttamente sia la risposta di successo che l’errore. Quando si utilizza la Clean Architecture, vengono creati mock per ogni livello: DataSource, Repository e UseCase — ciò consente di testare ogni livello in isolamento.

  • caso di successo — when(repo.getData()).thenReturn(Result.success(data)) → verificare state = Success(data).
  • caso di errore — when(repo.getData()).thenReturn(Result.error(exception)) → verificare state = Error(message).
  • stato di caricamento — verify che il ViewModel abbia impostato isLoading = true prima di chiamare il repository.

Domande frequenti

Qual è la differenza tra Mockito e MockK?

Mockito è una libreria per Java e Kotlin che utilizza proxy e riflessione. MockK è una libreria Kotlin-first con supporto per coroutine, funzioni di estensione e classi final senza configurazione aggiuntiva.

Come creare un mock per una classe final in Mockito?

A partire da Mockito 2.1, il mocking delle classi final è supportato tramite opt-in. Nella versione 5.x (mockito-inline), questa funzionalità è attivata per impostazione predefinita. Basta aggiungere la dipendenza mockito-inline e utilizzare il metodo standard mock().

Cos’è uno Spy in Mockito?

Uno Spy è un mock parziale che per impostazione predefinita chiama metodi reali ma consente di sovrascriverne alcuni tramite when().thenReturn(). Spy è utile per testare codice legacy quando non è possibile riscrivere l’intera classe.

Qual è la differenza tra thenReturn e thenAnswer?

thenReturn restituisce sempre lo stesso valore, indipendentemente dagli argomenti. thenAnswer calcola il valore restituito in base all’invocazione — argomenti della chiamata, il mock stesso e lo stato. Per risposte dinamiche, usa sempre thenAnswer.

Perché verify è importante per i test con mock?

Verify verifica non solo il risultato ma anche il processo — il fatto di accedere alla dipendenza. Ciò è fondamentale per i servizi che devono salvare dati o inviare notifiche. Senza verify, il test non rileverà che un metodo non ha chiamato save() o send().

Riepilogo

  • Mockito — una libreria per creare oggetti mock, lo standard de facto per il mocking in Java e Kotlin.
  • I mock vengono creati tramite mock(Class) o l’annotazione @Mock con MockitoExtension.
  • Stubbing tramite when().thenReturn() definisce il comportamento dei metodi del mock.
  • Verify verifica il fatto e il numero di chiamate ai metodi del mock con argomenti specificati.
  • @InjectMocks inietta automaticamente i mock nell’oggetto testato.
  • Integrazione Android — Mockito viene utilizzato per testare ViewModel, Repository e UseCase.
  • ArgumentCaptor cattura gli argomenti delle chiamate per la verifica dettagliata dei campi dell’oggetto.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche