→ Slide 1

Testowanie aplikacji Spring Boot

→ Slide 2

Testy jednostkowe

→ Slide 3

Struktura testów

→ Slide 4

Struktura projektu z testami

src/
├── main/
│   └── java/com/example/app/
│       ├── controller/
│       │   └── UserController.java
│       ├── service/
│       │   └── UserService.java
│       ├── repository/
│       │   └── UserRepository.java
│       └── model/
│           └── User.java
└── test/
    └── java/com/example/app/
        ├── controller/
        │   └── UserControllerTest.java
        ├── service/
        │   └── UserServiceTest.java
        ├── repository/
        │   └── UserRepositoryTest.java
        └── integration/
            └── UserFlowIntegrationTest.java
→ Slide 5

JUnit

Adnotacja @Test oznacza metodę jako testową.

→ Slide 6

Assercje

→ Slide 7

Przykład testu jednostkowego

Przykład prostego testu jednostkowego z użyciem JUnit:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
 
public class CalculatorTest {
 
    @Test
    public void testAddition() {
 
        // Arrange - przygotowanie danych testowych
        Calculator calculator = new Calculator();
 
        // Act - wykonanie testowanej metody
        int result = calculator.add(2, 3);
 
        // Assert - sprawdzenie wyników
        Assertions.assertEquals(5, result);
    }
}
→ Slide 8

Parametryzowane testy

@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
public void testIsPositive(int number) {
    Assertions.assertTrue(number > 0);
}
→ Slide 9

Mockito

when(mock.method()).thenReturn(value) - definiuje, co ma zwrócić mock dla danego wywołania.

verify(mock).method() - sprawdza, czy metoda została wywołana.

→ Slide 10

Adnotacje Mockito

→ Slide 11

Przykład

Test jednostkowy bez uruchamiania kontekstu Spring, z użyciem Mockito do mockowania zależności:

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
 
    @Mock
    private UserRepository userRepository;
 
    @InjectMocks
    private UserService userService;
 
    @Test
    void shouldReturnUserWhenExists() {
        User user = new User(1L, "Jan");
        when(userRepository.findById(1L)).thenReturn(Optional.of(user));
 
        User result = userService.getById(1L);
 
        assertThat(result.getName()).isEqualTo("Jan");
    }
}
→ Slide 12

WebMvcTest

→ Slide 13

Test kontrolera bez uruchamiania kontekstu Spring

Test kontrolera z użyciem @WebMvcTest, który uruchamia tylko warstwę webową:

@WebMvcTest(UserController.class)
class UserControllerTest {
    @Autowired
    private MockMvc mockMvc;
 
    @MockBean
    private UserService userService;
 
    @Test
    void shouldReturnUser() throws Exception {
        when(userService.getById(1L)).thenReturn(new User(1L, "Jan"));
 
        mockMvc.perform(get("/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("Jan"));
    }
}
→ Slide 14

Test kontrolera z uruchomieniem kontekstu Spring

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
    @Autowired
    private MockMvc mockMvc;
 
    @Test
    void shouldReturnUserList() throws Exception {
        mockMvc.perform(get("/users"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$[0].name").value("Jan"));
    }
}
→ Slide 15

Test bazy danych

@DataJpaTest
class UserRepositoryTest {  
    @Autowired
    private UserRepository userRepository;
 
     @Test
    void shouldFindUserByEmail() {
        User user = new User();
        user.setName("Jan");
        user.setEmail("jan@test.pl");
        userRepository.save(user);
 
        Optional<User> result = userRepository.findByEmail("jan@test.pl");
 
        assertThat(result).isPresent();
    }
}
→ Slide 16

Test integracyjny

@SpringBootTest
class UserFlowIntegrationTest {
 
    @Autowired
    private UserService userService;
 
    @Test
    void shouldCreateUser() {
        User created = userService.create("Jan", "jan@test.pl");
 
        assertThat(created.getId()).isNotNull();
    }
}
→ Slide 17

JavaDoc

→ Slide 18

Przykład komentarza JavaDoc

/**
 * Serwis odpowiedzialny za zarządzanie użytkownikami.
 */
public class UserService {
 
    /**
     * Zwraca użytkownika na podstawie identyfikatora.
     *
     * @param id identyfikator użytkownika
     * @return znaleziony użytkownik
     * @throws UserNotFoundException gdy użytkownik nie istnieje
     */
    public User getById(Long id) {
        // ...
        return null;
    }
}
→ Slide 19

Najważniejsze tagi JavaDoc

→ Slide 20

Dokumentacja