0Pricing
Java Academy · Lezione

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 — stubbed

Annotazione @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 interaction

Verifica 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 send

Matcher 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

  1. Test parametrizzati con @CsvSource e @MethodSource
  2. Mockito avanzato: ArgumentCaptor e spy
  3. Slice di test Spring Boot: @WebMvcTest e @DataJpaTest
  4. Testcontainers: test di integrazione con database reali
← Torna a Java Academy