Mockito zaawansowane: przechwytywanie argumentów i szpiegi
Proszę przechwytywać argumenty metod za pomocą ArgumentCaptor i częściowo mockować rzeczywiste obiekty przez Mockito.spy.
Mockito zaawansowane: przechwytywanie argumentów i szpiegi to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
ArgumentCaptor: przechwytywanie argumentów metod
ArgumentCaptor przechwytuje argumenty przekazane do mockowanej metody, dzięki czemu można je sprawdzić. Jest przydatny, gdy argument jest tworzony wewnątrz testowanego systemu i nie można uzyskać do niego bezpośredniego dostępu.
Tworzenie i używanie ArgumentCaptor
Utwórz captor dla typu argumentu, przekaż captor.capture() jako matcher argumentu w verify(), a następnie wywołaj captor.getValue(), aby pobrać przechwycony argument.
@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"));
}Adnotacja @Captor
Używaj @Captor razem z @ExtendWith(MockitoExtension.class), aby uniknąć rozwlekłych wywoł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());
}
}Przechwytywanie wielu wywołań
Używaj captor.getAllValues(), gdy metoda jest wywoływana wiele razy. Zwraca ono listę wszystkich przechwyconych wartości w kolejności wywołań.
verify(emailService, times(3)).send(emailCaptor.capture());
List<EmailMessage> messages = emailCaptor.getAllValues();
assertEquals(3, messages.size());
assertEquals("Confirmation", messages.get(0).getSubject());Szpiegi Mockito: częściowe mockowanie
Mockito.spy() opakowuje rzeczywisty obiekt. Wszystkie metody działają normalnie, chyba że jawnie je zamockujesz. Używaj tego rozwiązania, gdy trzeba przetestować klasę, która ma pewne trudne do testowania zależności, ale w większości działa poprawnie.
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 — stubbedAdnotacja @Spy
Używaj @Spy razem z @ExtendWith(MockitoExtension.class), aby tworzyć szpiegi. Pole musi zostać zainicjalizowane (bezpośrednio lub za pomocą @Spy UserService svc = new UserService(repo);).
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Spy
OrderService orderService = new OrderService(mockRepo, mockEmail);
}Szpiegowanie beanów Spring za pomocą @SpyBean
W testach Spring Boot adnotacja @SpyBean opakowuje istniejący bean Spring w szpiega Mockito — zachowuje on rzeczywiste działanie, chyba że zostanie zamockowany. Jest używana razem z @SpringBootTest.
@SpringBootTest
class IntegrationTest {
@SpyBean EmailService emailService;
@Test
void order_sends_email() {
orderService.placeOrder(cart);
verify(emailService).sendConfirmation(any());
}
}doReturn a when().thenReturn() w przypadku szpiegów
W przypadku szpiegów używaj doReturn(value).when(spy).method() zamiast when(spy.method()).thenReturn(value). Postać when(spy.method()) faktycznie wywołuje rzeczywistą metodę, co może powodować skutki uboczne.
// 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!Sprawdzanie braku interakcji
Używaj verifyNoInteractions(mock), aby sprawdzić, czy mock nigdy nie został wywołany, oraz verifyNoMoreInteractions(mock) po wszystkich oczekiwanych wywołaniach, aby wykrywać nieoczekiwane interakcje.
verifyNoInteractions(emailService); // never called
verify(repo).save(any());
verifyNoMoreInteractions(repo); // save() was the only interactionSprawdzanie kolejności za pomocą InOrder
Używaj InOrder, aby sprawdzać, czy mockowane metody zostały wywołane w określonej kolejności.
InOrder inOrder = inOrder(repo, emailService);
inOrder.verify(repo).save(any());
inOrder.verify(emailService).send(any()); // save happened BEFORE sendMatchery argumentów
Łącz captory z matcherami: any(), eq(), anyString(), argThat(predicate). Jeśli jeden z argumentów używa matchera, wszystkie argumenty muszą używać matcherów.
verify(repo).save(argThat(user ->
user.getEmail().endsWith("@example.com") &&
user.getStatus() == UserStatus.ACTIVE));Szybkie sprawdzenie
Dlaczego podczas mockowania szpiega należy używać doReturn zamiast when().thenReturn()?
Podsumowanie
ArgumentCaptor przechwytuje argumenty, aby można je było sprawdzić po wywołaniu. Szpiegi opakowują rzeczywiste obiekty i przekazują do nich wywołania, chyba że metody zostaną zamockowane. Używaj doReturn w przypadku szpiegów. Używaj @SpyBean w testach integracyjnych Spring. Sprawdzaj kolejność wywołań za pomocą InOrder.
Ucz się Java dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 104
- Lekcje
- 374
Często zadawane pytania
Czy lekcja „Mockito zaawansowane: przechwytywanie argumentów i szpiegi” jest bezpłatna?
Tak — pełny tekst „Mockito zaawansowane: przechwytywanie argumentów i szpiegi” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Mockito zaawansowane: przechwytywanie argumentów i szpiegi”?
Proszę przechwytywać argumenty metod za pomocą ArgumentCaptor i częściowo mockować rzeczywiste obiekty przez Mockito.spy. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Mockito zaawansowane: przechwytywanie argumentów i szpiegi”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Testy parametryzowane za pomocą @CsvSource i @MethodSource
- Mockito zaawansowane: przechwytywanie argumentów i szpiegi
- Wycinanie testów Spring Boot: @WebMvcTest i @DataJpaTest
- Testcontainers: integracyjne testy z rzeczywistą bazą danych