Mockito avanzato: ArgumentCaptor e spy
Catturi gli argomenti dei metodi con ArgumentCaptor e simuli parzialmente oggetti reali con Mockito.spy.
Mockito avanzato: ArgumentCaptor e spy è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.
ArgumentCaptor: acquisizione degli argomenti dei metodi
ArgumentCaptor acquisisce gli argomenti passati a un metodo simulato, così può verificarli. È utile quando l'argomento viene creato all'interno del sistema sottoposto a test e non è possibile accedervi direttamente.
Creazione e utilizzo di ArgumentCaptor
Crei un captor per il tipo di argomento, passi captor.capture() come matcher dell'argomento in verify(), quindi chiami captor.getValue() per ottenere l'argomento acquisito.
@Test
void sends_correct_email() {
ArgumentCaptor<EmailMessage> captor = ArgumentCaptor.forClass(EmailMessage.class);
userService.register(new CreateUserRequest("alice@example.com"));
verify(emailService).send(captor.capture());
EmailMessage msg = captor.getValue();
assertEquals("alice@example.com", msg.getTo());
assertTrue(msg.getSubject().contains("Welcome"));
}Annotazione @Captor
Utilizzi @Captor con @ExtendWith(MockitoExtension.class) per evitare chiamate verbose a ArgumentCaptor.forClass().
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock EmailService emailService;
@Captor ArgumentCaptor<EmailMessage> emailCaptor;
@Test
void captures_email() {
// ...
verify(emailService).send(emailCaptor.capture());
assertEquals("Welcome!", emailCaptor.getValue().getSubject());
}
}Acquisizione di più chiamate
Utilizzi captor.getAllValues() quando il metodo viene chiamato più volte. Restituisce un elenco di tutti i valori acquisiti nell'ordine delle chiamate.
verify(emailService, times(3)).send(emailCaptor.capture());
List<EmailMessage> messages = emailCaptor.getAllValues();
assertEquals(3, messages.size());
assertEquals("Confirmation", messages.get(0).getSubject());Mockito Spies: mock parziale
Mockito.spy() avvolge un oggetto reale. Tutti i metodi si comportano normalmente, salvo quando vengono configurati esplicitamente con uno stub. Lo utilizzi quando deve testare una classe che presenta alcune dipendenze difficili da testare, ma che per il resto funziona correttamente.
List<String> realList = new ArrayList<>();
List<String> spy = Mockito.spy(realList);
spy.add("hello"); // calls real ArrayList.add()
System.out.println(spy.size()); // 1 — real method called
doReturn(42).when(spy).size(); // stub just size()
System.out.println(spy.size()); // 42 — stubbedAnnotazione @Spy
Utilizzi @Spy con @ExtendWith(MockitoExtension.class) per creare spy. Il campo deve essere inizializzato, inline oppure tramite @Spy UserService svc = new UserService(repo);.
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Spy
OrderService orderService = new OrderService(mockRepo, mockEmail);
}Spy dei bean Spring con @SpyBean
Nei test Spring Boot, @SpyBean avvolge un bean Spring esistente in uno spy Mockito: il comportamento resta reale salvo quando viene configurato uno stub. Si usa insieme a @SpringBootTest.
@SpringBootTest
class IntegrationTest {
@SpyBean EmailService emailService;
@Test
void order_sends_email() {
orderService.placeOrder(cart);
verify(emailService).sendConfirmation(any());
}
}doReturn vs when().thenReturn() per gli spy
Per gli spy, utilizzi doReturn(value).when(spy).method() invece di when(spy.method()).thenReturn(value). La forma when(spy.method()) chiama effettivamente il metodo reale, causando potenzialmente effetti collaterali.
// Correct for spies:
doReturn(List.of()).when(spy).findAll();
// WRONG for spies — calls real findAll() first:
when(spy.findAll()).thenReturn(List.of()); // real method called!Verifica dell'assenza di interazioni
Utilizzi verifyNoInteractions(mock) per verificare che un mock non sia mai stato chiamato e verifyNoMoreInteractions(mock) dopo tutte le chiamate attese per individuare quelle impreviste.
verifyNoInteractions(emailService); // never called
verify(repo).save(any());
verifyNoMoreInteractions(repo); // save() was the only interactionVerifica con InOrder
Utilizzi InOrder per verificare che i metodi simulati siano stati chiamati in un ordine specifico.
InOrder inOrder = inOrder(repo, emailService);
inOrder.verify(repo).save(any());
inOrder.verify(emailService).send(any()); // save happened BEFORE sendMatcher degli argomenti
Combini i captor con i matcher: any(), eq(), anyString(), argThat(predicate). Se un argomento utilizza un matcher, tutti gli argomenti devono utilizzarne uno.
verify(repo).save(argThat(user ->
user.getEmail().endsWith("@example.com") &&
user.getStatus() == UserStatus.ACTIVE));Verifica rapida
Perché utilizzare doReturn invece di when().thenReturn() quando si configura uno stub per uno spy?
Riepilogo
ArgumentCaptor acquisisce gli argomenti per poterli verificare dopo la chiamata. Gli spy avvolgono oggetti reali e delegano a essi le chiamate, salvo quando vengono configurati con uno stub. Utilizzi doReturn per gli spy. Utilizzi @SpyBean per i test di integrazione Spring. Verifichi l'ordine delle chiamate con InOrder.
Domande Frequenti
La lezione «Mockito avanzato: ArgumentCaptor e spy» è gratuita?
Sì — il testo completo di «Mockito avanzato: ArgumentCaptor e spy» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.
Cosa imparerò in «Mockito avanzato: ArgumentCaptor e spy»?
Catturi gli argomenti dei metodi con ArgumentCaptor e simuli parzialmente oggetti reali con Mockito.spy. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Java Academy?
Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Mockito avanzato: ArgumentCaptor e spy»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Java Academy?
Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Test parametrizzati con @CsvSource e @MethodSource
- Mockito avanzato: ArgumentCaptor e spy
- Slice di test Spring Boot: @WebMvcTest e @DataJpaTest
- Testcontainers: test di integrazione con database reali