Vai al contenuto

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:

mock-maker-inline

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 @Mock e @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; utilizzare doReturn()_ 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;