Testowanie aplikacji Spring Boot
Testy jednostkowe
- JUnit 5 - framework do pisania i uruchamiania testów jednostkowych w Javie
- Mockito - framework do mockowania zależności w testach jednostkowych.
- Spring Boot Test - wsparcie dla testów jednostkowych i integracyjnych.
spring-boot-starter-test- starter zawierający wszystkie potrzebne zależności (JUnit, Mockito, AssertJ).@SpringBootTest- uruchamia kontekst Spring podczas testów.@MockBean- tworzy mocki dla zależności.@WebMvcTest- testowanie warstwy webowej (kontrolerów).@DataJpaTest- testowanie warstwy dostępu do danych (repozytoriów).
Struktura testów
- Testy jednostkowe - testowanie pojedynczych klas i metod, izolacja od reszty aplikacji.
- Testy integracyjne - testowanie współpracy między komponentami, uruchomienie kontekstu Spring.
- Testy end-to-end - testowanie całej aplikacji, symulacja rzeczywistego użytkowania.
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
JUnit
- JUnit to framework do pisania testów jednostkowych w Javie.
- Przypadek testowy - metoda testowa, która sprawdza poprawność działania konkretnej funkcjonalności.
Adnotacja @Test oznacza metodę jako testową.
- Adnotacje - zarządzanie cyklem życia testów:
@Test- oznacza metodę jako testową.@BeforeEach- metoda wykonywana przed każdym testem.@AfterEach- metoda wykonywana po każdym teście.@BeforeAll- metoda wykonywana raz przed wszystkimi testami.@AfterAll- metoda wykonywana raz po wszystkich testach.
Assercje
- Assercje - metody sprawdzające, czy wynik testu jest zgodny z oczekiwaniami.
assertEquals(expected, actual)- sprawdza równość wartości.assertTrue(condition)- sprawdza, czy warunek jest prawdziwy.assertFalse(condition)- sprawdza, czy warunek jest fałszywy.assertNotNull(object)- sprawdza, czy obiekt nie jest null.assertThrows(exceptionClass, executable)- sprawdza, czy wykonanie kodu rzuca określony wyjątek.
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); } }
Parametryzowane testy
- Parametryzowane testy - pozwalają na uruchomienie tej samej metody testowej z różnymi zestawami danych.
- Adnotacja
@ParameterizedTest- oznacza metodę jako parametryzowany test. - Źródła danych:
@ValueSource- pojedyncze wartości (np. liczby, stringi).@CsvSource- dane w formacie CSV (np. „2,3,5”).@MethodSource- dane dostarczane przez metodę zwracającą strumień argumentów.
@ParameterizedTest @ValueSource(ints = {1, 2, 3}) public void testIsPositive(int number) { Assertions.assertTrue(number > 0); }
Mockito
- Mockito to framework do tworzenia mocków i stubów w testach jednostkowych.
- Pozwala na izolację testowanej klasy od jej zależności.
- Mock - obiekt zastępczy, który imituje zachowanie prawdziwego obiektu.
- Stubbing - definiowanie zachowania mocka dla określonych wywołań metod.
when(mock.method()).thenReturn(value) - definiuje, co ma zwrócić mock dla danego wywołania.
- Verify - sprawdzanie, czy określone metody zostały wywołane na mocku.
verify(mock).method() - sprawdza, czy metoda została wywołana.
Adnotacje Mockito
@ExtendWith(MockitoExtension.class)- integracja z JUnit 5.@Mock- tworzy atrapę (mock) dla danej klasy.@InjectMocks- wstrzykuje mocki do testowanej klasy.@Spy- tworzy częściowy mock, który zachowuje się jak prawdziwy obiekt, ale pozwala na stubbing i weryfikację.
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"); } }
WebMvcTest
@WebMvcTest- adnotacja do testowania warstwy webowej (kontrolerów) bez uruchamiania całego kontekstu Spring.- Pozwala na testowanie kontrolerów w izolacji, z mockowanymi zależnościami (serwisami).
- Użycie
MockMvc- narzędzie do symulowania żądań HTTP i sprawdzania odpowiedzi. - Metody:
perform()- wykonuje żądanie HTTP.andExpect()- sprawdza oczekiwane wyniki (status, nagłówki, body).jsonPath()- sprawdza zawartość JSON w odpowiedzi.status().isOk()- sprawdza, czy status odpowiedzi to 200 OK.content().string()- sprawdza zawartość odpowiedzi jako string.jsonPath()- sprawdza zawartość odpowiedzi jako JSON.
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")); } }
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")); } }
Test bazy danych
@DataJpaTest- adnotacja do testowania warstwy dostępu do danych (repozytoriów) bez uruchamiania całego kontekstu Spring.- Użycie wbudowanej bazy danych H2 do testów, która jest automatycznie konfigurowana przez Spring Boot.
- Testowanie encji, zapytań i operacji CRUD bez uruchamiania całej aplikacji.
spring-boot-starter-data-jpa-test- starter zawierający zależności do testowania JPA.'
@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(); } }
Test integracyjny
- Testowanie współpracy między komponentami, uruchomienie kontekstu Spring.
- Testowanie całej ścieżki od kontrolera, przez serwis, do repozytorium i bazy danych.
@SpringBootTest class UserFlowIntegrationTest { @Autowired private UserService userService; @Test void shouldCreateUser() { User created = userService.create("Jan", "jan@test.pl"); assertThat(created.getId()).isNotNull(); } }
JavaDoc
- JavaDoc to narzędzie do generowania dokumentacji API z komentarzy w kodzie źródłowym.
- Komentarze JavaDoc umieszczamy nad klasami, metodami i polami, używając specjalnej składni.
- JavaDoc pozwala na tworzenie czytelnej i zrozumiałej dokumentacji dla programistów korzystających z naszego kodu.
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; } }
Najważniejsze tagi JavaDoc
@param- opisuje parametr metody@return- opisuje wartość zwracaną przez metodę@throws- opisuje wyjątki, które metoda może rzucić@author- autor klasy lub metody@version- wersja klasy lub metody@see- odwołanie do innej klasy lub metody@deprecated- oznacza, że element jest przestarzały
Dokumentacja
- JUnit - oficjalna dokumentacja JUnit
- Mockito - framework do mockowania zależności w testach jednostkowych.
- Spring Boot Test - wsparcie dla testów jednostkowych i integracyjnych.
- JavaDoc - oficjalna dokumentacja JavaDoc
