HTML_TAG_147_ __HTML_TAG_150_📄 Generare Mockito PDF Guida_HTML_TAG_151
Mockito Cheatsheet¶
Installazione¶
Tabella_166
Comandi di base¶
Tabella_167_
Annotation-Based Setup¶
Tabella_168_
Stubbing Methods¶
Tabella_169
Argument Matchers¶
Tabella_170_
Metodi di verifica¶
TABELLA 171_
Argument Captors¶
Tabella_172_ Traduzione:
Caratteristiche avanzate¶
TABELLA 173_
BDD Style (Behavior-Driven Development)¶
Tabella_174_
Configurazione¶
Test Class Setup con JUnit 5¶
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Mock
private EmailService emailService;
@InjectMocks
private UserService userService;
@Test
void testUserCreation() {
User user = new User("John");
when(userRepository.save(any(User.class))).thenReturn(user);
User result = userService.createUser("John");
verify(userRepository).save(any(User.class));
verify(emailService).sendWelcomeEmail(user);
assertEquals("John", result.getName());
}
}
Test Class Setup con JUnit 4¶
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.*;
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Before
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testUserCreation() {
// Test implementation
}
}
Impostazioni personalizzate Mock¶
// Create mock with custom settings
UserService mock = mock(UserService.class, withSettings()
.name("customMockName")
.defaultAnswer(RETURNS_SMART_NULLS)
.serializable()
.verboseLogging());
// Create mock with invocation listeners
UserService mock = mock(UserService.class, withSettings()
.invocationListeners(invocation -> {
System.out.println("Method called: " + invocation.getMethod());
}));
Mockito Configuration File¶
Crea mockito-extensions/org.mockito.plugins.MockMaker_ nelle risorse di prova:
Ciò consente di sfruttare le classi e i metodi finali senza una dipendenza esplicita.
Common Use Cases¶
Use Case 1: Testing Service Layer with Repository¶
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void shouldFindUserById() {
// Given
User expectedUser = new User(1L, "John");
when(userRepository.findById(1L)).thenReturn(Optional.of(expectedUser));
// When
User result = userService.getUserById(1L);
// Then
assertEquals("John", result.getName());
verify(userRepository).findById(1L);
}
}
Use Case 2: Testing Exception Handling¶
@Test
void shouldHandleUserNotFoundException() {
// Given
when(userRepository.findById(999L))
.thenThrow(new UserNotFoundException("User not found"));
// When & Then
assertThrows(UserNotFoundException.class, () -> {
userService.getUserById(999L);
});
verify(userRepository).findById(999L);
}
Use Case 3: Verification Method Call Order¶
@Test
void shouldProcessUserInCorrectOrder() {
// Given
User user = new User("John");
// When
userService.registerUser(user);
// Then
InOrder inOrder = inOrder(userRepository, emailService, auditService);
inOrder.verify(userRepository).save(user);
inOrder.verify(emailService).sendWelcomeEmail(user);
inOrder.verify(auditService).logRegistration(user);
}
Use Case 4: Capturing and Asserting Arguments¶
@Test
void shouldSaveUserWithCorrectData() {
// Given
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
// When
userService.createUser("John", "john@example.com");
// Then
verify(userRepository).save(userCaptor.capture());
User capturedUser = userCaptor.getValue();
assertEquals("John", capturedUser.getName());
assertEquals("john@example.com", capturedUser.getEmail());
assertNotNull(capturedUser.getCreatedDate());
}
Use Case 5: Testing Asynchronous Codice¶
@Test
void shouldProcessAsyncOperation() {
// Given
when(asyncService.processData(anyString()))
.thenReturn(CompletableFuture.completedFuture("result"));
// When
userService.processUserAsync("user123");
// Then - verify within timeout for async operations
verify(asyncService, timeout(1000)).processData("user123");
verify(notificationService, timeout(1000)).sendNotification(any());
}
Use Case 6: Mocking Metodi statici¶
@Test
void shouldMockStaticUtilityMethod() {
try (MockedStatic<DateUtils> dateUtils = mockStatic(DateUtils.class)) {
// Given
LocalDate fixedDate = LocalDate.of(2024, 1, 1);
dateUtils.when(DateUtils::getCurrentDate).thenReturn(fixedDate);
// When
User user = userService.createUser("John");
// Then
assertEquals(fixedDate, user.getRegistrationDate());
dateUtils.verify(DateUtils::getCurrentDate);
}
}
Use Case 7: Usare Spies per il mocking parziale¶
@Test
void shouldUseSpyForPartialMocking() {
// Given
UserService realService = new UserService(userRepository);
UserService spyService = spy(realService);
// Stub only specific method
doReturn(true).when(spyService).isValidEmail(anyString());
// When
User user = spyService.createUser("John", "invalid-email");
// Then - real methods called except stubbed ones
verify(spyService).isValidEmail("invalid-email");
verify(userRepository).save(any(User.class));
}
Migliori Pratiche¶
-
Utilizzare le annotazioni
@Mocke@InjectMocks___ invece di creare mock manuale per il codice di prova più pulito e l'iniezione automatica della dipendenza -
Preferire
when().thenReturn()_________INLINE_CODE_124_ per mocking regolare; utilizzaredoReturn()_ solo per spie o quando i metodi di stubbing che gettano eccezioni -
Non mock tipi che non possiedi (ad esempio, librerie di terze parti) - invece, creare interfacce wrapper e mock quelle per mantenere il controllo sui confini di prova
-
Verificare il comportamento, non i dettagli di implementazione - concentrarsi sul test che il codice fa, non su come lo fa; evitare over-verification che rende i test fragili
-
**Utilizzare i captori dell'argomento con parsimonia ** - solo quando è necessario affermare i valori complessi dell'argomento; preferire gli abbinatori dell'argomento per una semplice verifica
-Mantenere un'affermazione logica per test - i test dovrebbero verificare un singolo comportamento per rendere i guasti facili da diagnosticare e mantenere
-
Clean up static mocks correttamente - utilizzare sempre prove con risorse quando si mocking metodi statici per evitare perdite di stato tra i test
-
Utilizza
lenient()per le stube opzionali - quando i metodi di stubbing che potrebbero non essere chiamati in tutti gli scenari di prova, contrassegnarli come lenienti per evitare errori di stubbing non necessari -
Avoid mocking value objects - mock only objects with behavior (servizi, repository); utilizzare istanze reali per DTO, entità e oggetti di valore
-
Name your mocks descriptively - quando debug test complessi, utilizzare
mock(Class.class, "descriptiveName")per rendere i messaggi di errore più chiaro
Risoluzione dei problemi¶
Tabella_175_¶
Riferimento rapido Importa dichiarazioni:
import static org.mockito.Mockito.*;
import static org.mockito.BDDMockito.*;
import static org.mockito.ArgumentMatchers.*;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.Captor;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;