Zum Hauptinhalt springen

Woche 7, Tag 5 — Integration Testing und Testing-Review für die Prüfung

Ziel

Heute schließt du das Thema Testing für die Spring-Professional-Prüfung ab.

Die Kernfragen:

  1. Was ist ein Integrationstest?
  2. Was macht @SpringBootTest?
  3. Wann solltest du @SpringBootTest nutzen?
  4. Was ist der Unterschied zwischen @SpringBootTest und Slice-Tests?
  5. Wie testest du vollständige Web-Flows mit MockMvc?
  6. Wie testest du mit einem echten HTTP-Port?
  7. Wie testest du mit Testcontainers?
  8. Wie funktionieren Transaktionen und Rollback in Tests?
  9. Welches Testing-Wissen reicht für die Spring-Professional-Prüfung?
  10. Was sind die wichtigsten Prüfungsfallen?

1. Kurz-Wiederholung aus Woche 7

In Woche 7 hast du gelernt:

  • Unit-Tests testen eine Klasse ohne Spring.
  • @WebMvcTest testet den MVC-/Controller-Slice.
  • @DataJpaTest testet den JPA-/Repository-Slice.
  • @SpringBootTest lädt den vollständigen Spring-Boot-Application-Context.
  • MockMvc testet HTTP-Verhalten ohne echten Server.
  • TestEntityManager hilft in JPA-Tests.
  • spring-security-test hilft beim Testen gesicherter Endpoints.
  • Testcontainers kann echte Infrastruktur für Integrationstests bereitstellen.

Merksatz:


Wähle den kleinsten Test, der das Verhalten beweist.

2. Was ist ein Integrationstest?

Ein Integrationstest prüft, dass mehrere Teile der Anwendung zusammenarbeiten.

Beispiele:


Controller + Service + Repository
Security + Controller + Service
Service + Repository + Datenbank
Application Configuration + Beans
REST API + Datenbank
Anwendung + Mock für externen Service

Ein Unit-Test fragt:


Funktioniert diese Klasse allein?

Ein Integrationstest fragt:


Arbeiten diese Teile zusammen?

Merksatz:

Integrationstests beweisen die Zusammenarbeit zwischen Komponenten.


3. Was ist @SpringBootTest?

@SpringBootTest lädt den Spring-Boot-Application-Context.

Beispiel:


@SpringBootTest
class ApplicationContextTest {

@Test
void contextLoads() {
}
}

Das prüft:


Kann Spring den Application Context starten?
Können Beans erstellt werden?
Können Dependencies injiziert werden?
Ist die Konfiguration gültig?
Funktioniert Auto-Configuration?

Merksatz:

@SpringBootTest startet den vollständigen Spring-Boot-Context.


4. Warum contextLoads nützlich ist

Ein einfacher Test:


@SpringBootTest
class ApplicationContextTest {

@Test
void contextLoads() {
}
}

Er sieht leer aus, ist aber nicht nutzlos.

Er beweist:


Spring kann die Anwendung starten.
Kein erforderlicher Bean fehlt.
Konfigurationsproperties sind gültig genug.
Bean-Dependencies können verdrahtet werden.

Aber er beweist kein Business-Verhalten.

Merksatz:

contextLoads prüft den Start, nicht Features.


5. Wann solltest du @SpringBootTest nutzen?

Nutze @SpringBootTest, wenn du brauchst:


vollständigen Application Context
echte Service-Beans
echte Repositories
echte Security-Konfiguration
mehrere Layer zusammen
Application Configuration
Setup für externe Integration
Testcontainers
vollständigen Request-Flow

Nutze es nicht für jeden Test.

Für einfache Service-Logik:


Unit-Test ist besser

Nur für Controller:


@WebMvcTest ist besser

Nur für Repository:


@DataJpaTest ist besser

Merksatz:

Nutze @SpringBootTest nur, wenn der Test die vollständige App braucht.


6. @SpringBootTest vs. Slice-Tests

TestUmfangGut für
Unit-Testeine Klasse, ohne SpringBusiness-Logik
@WebMvcTestMVC-SliceController, Validation, JSON
@DataJpaTestJPA-SliceRepositories, Mappings, Queries
@SpringBootTestvollständiger App-ContextIntegrations-Flow

Merksatz:


Slice-Tests sind fokussiert.
SpringBootTest ist vollständig.

7. @SpringBootTest mit MockMvc

Für vollständige Web-Integration ohne echten Server:


@SpringBootTest
@AutoConfigureMockMvc
class TaskApiIntegrationTest {

@Autowired
private MockMvc mockMvc;

@Test
void createsTask() throws Exception {
mockMvc.perform(post("/api/tasks")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"title": "Learn Integration Tests"
}
"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.title").value("Learn Integration Tests"));
}
}

Das kann testen:


Spring-Security-Filter
Controller
Validation
Service
Repository
Datenbank
JSON-Serialisierung
Exception Handling

Merksatz:

@SpringBootTest + MockMvc testet einen vollständigen MVC-Flow ohne echten Server.


8. Beispiel: vollständiger Flow-Test

Feature:


POST /api/tasks erstellt einen Task.
GET /api/tasks/{id} gibt den Task zurück.

Test:


@SpringBootTest
@AutoConfigureMockMvc
class TaskApiIntegrationTest {

@Autowired
private MockMvc mockMvc;

@Test
void createsAndReadsTask() throws Exception {
MvcResult createResult = mockMvc.perform(post("/api/tasks")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"title": "Integration Task"
}
"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.title").value("Integration Task"))
.andReturn();

String responseBody = createResult.getResponse().getContentAsString();

Long taskId = JsonPath.read(responseBody, "$.id");

mockMvc.perform(get("/api/tasks/{id}", taskId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(taskId))
.andExpect(jsonPath("$.title").value("Integration Task"));
}
}

Das beweist, dass viele Layer zusammenarbeiten.

Merksatz:

Integrationstests können einen realistischen User-Flow testen.


9. @SpringBootTest Web Environment

@SpringBootTest kann mit verschiedenen Web-Environments laufen.

Gängige Modi:


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

Bedeutung:

ModusBedeutung
MOCKMock-Servlet-Environment, kein echter Server
RANDOM_PORTstartet echten Server auf zufälligem Port
DEFINED_PORTstartet echten Server auf konfiguriertem Port
NONEkein Web-Environment

Merksatz:

MOCK ist üblich mit MockMvc; RANDOM_PORT startet einen echten Server.


10. Echter HTTP-Test mit Random Port

Beispiel:


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class TaskApiRealHttpTest {

@Autowired
private TestRestTemplate restTemplate;

@Test
void healthEndpointIsAvailable() {
ResponseEntity<String> response =
restTemplate.getForEntity("/actuator/health", String.class);

assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}

Das startet einen eingebetteten Server auf einem zufälligen Port.

Nützlich, wenn du testen willst:


echte HTTP-Layer
echtes Server-Verhalten
HTTP-Client-Verhalten
vollständigen Request-/Response-Stack

Merksatz:

Nutze RANDOM_PORT, wenn du echtes HTTP willst.


11. MockMvc vs. TestRestTemplate

ToolServer?Gut für
MockMvckein echter ServerMVC-Integrationstests
TestRestTemplateechter Serverechte HTTP-Integrationstests

MockMvc:


mockMvc.perform(get("/api/tasks"))

TestRestTemplate:


restTemplate.getForEntity("/api/tasks", String.class)

Merksatz:

MockMvc ist serverlos; TestRestTemplate nutzt echtes HTTP.


12. Integrationstest mit Datenbank

Ein vollständiger Integrationstest kann nutzen:


Controller
Service
Repository
Datenbank

Beispiel:


@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class TaskIntegrationTest {

@Autowired
private MockMvc mockMvc;

@Autowired
private TaskRepository taskRepository;

@Test
void createdTaskIsStoredInDatabase() throws Exception {
mockMvc.perform(post("/api/tasks")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"title": "Stored Task"
}
"""))
.andExpect(status().isCreated());

assertThat(taskRepository.existsByTitle("Stored Task")).isTrue();
}
}

Der Test prüft sowohl API-Verhalten als auch Datenbankzustand.

Merksatz:

Vollständige Integrationstests können externe Response und internen Datenbankzustand verifizieren.


13. Test-Transaktionen und Rollback

Spring-Tests können transaktional sein.

Beispiel:


@SpringBootTest
@Transactional
class TaskIntegrationTest {
}

Standardmäßig rollen transaktionale Testmethoden nach dem Test zurück.

Bedeutung:


Test erstellt Daten
Test verifiziert Verhalten
Test endet
Transaktion rollt zurück
Datenbank ist wieder sauber

Merksatz:

Transaktionale Tests rollen üblicherweise nach jedem Test zurück.


14. Wichtige Transaktions-Falle mit MockMvc

Wenn die Testmethode @Transactional ist, der Request aber in einem anderen Thread oder im Real-Server-Modus verarbeitet wird, kann das Rollback-Verhalten anders sein.

Mit MockMvc und Mock-Servlet-Environment ist Rollback meist einfacher.

Mit echtem HTTP und RANDOM_PORT kann die Server-Request-Verarbeitung eine andere Transaktion als die Testmethode nutzen.

Dieses Muster kann also knifflig sein:


@SpringBootTest(webEnvironment = RANDOM_PORT)
@Transactional
class RealHttpTest {
}

Merksatz:

Rollback-Verhalten ist einfacher bei Repository-Tests und MockMvc als bei Real-Server-Tests.


15. Strategien für saubere Datenbank

Bei Integrationstests ist Datenbank-Cleanup wichtig.

Optionen:


Transaktions-Rollback
Daten vor jedem Test löschen
Daten nach jedem Test löschen
frischen Testcontainer nutzen
@Sql-Cleanup-Skripte nutzen
Database-Cleaner-Utility nutzen

Gute Regel:


Jeder Test sollte unabhängig sein.

Merksatz:

Integrationstests brauchen eine klare Datenbank-Cleanup-Strategie.


16. @Sql in Integrationstests

Beispiel:


@SpringBootTest
@AutoConfigureMockMvc
@Sql("/sql/clean.sql")
@Sql("/sql/test-data.sql")
class TaskApiIntegrationTest {
}

Beispiel-Cleanup:


delete from tasks;
delete from clients;

Nützlich, wenn:


Testdaten komplex sind
viele Tests dasselbe Setup brauchen
Datenbank explizit bereinigt werden muss

Merksatz:

@Sql kann Datenbankzustand für Integrationstests vorbereiten oder bereinigen.


17. Testcontainers für Integrationstests

Testcontainers kann eine echte Datenbank in Docker starten.

Beispiel:


PostgreSQL-Container
Redis-Container
Kafka-Container
RabbitMQ-Container
LocalStack-Container

Warum nützlich?


echtes Infrastruktur-Verhalten
produktionsähnliche Datenbank
isolierte Testumgebung
funktioniert in CI
weniger lokales Setup
Native SQL wird realistisch getestet

Merksatz:

Testcontainers liefert produktionsähnliche Infrastruktur für Tests.


18. PostgreSQL-Testcontainers-Beispiel

Dependencies:


testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql")
testImplementation("org.springframework.boot:spring-boot-testcontainers")

Test:


@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class TaskApiPostgresIntegrationTest {

@Container
@ServiceConnection
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:16");

@Autowired
private MockMvc mockMvc;

@Test
void createsTaskUsingRealPostgres() throws Exception {
mockMvc.perform(post("/api/tasks")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"title": "Postgres Task"
}
"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.title").value("Postgres Task"));
}
}

Wichtig:


Das braucht Docker.

Merksatz:

Nutze Testcontainers, wenn Datenbank-Realismus wichtig ist.


19. Testcontainers ohne @ServiceConnection

Älterer/manueller Stil:


@SpringBootTest
@Testcontainers
class TaskApiPostgresIntegrationTest {

@Container
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:16");

@DynamicPropertySource
static void configureDatasource(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
}

Merksatz:

DynamicPropertySource verbindet Container-Properties mit Spring.


20. Externe Services testen

Rufe in normalen automatisierten Tests keine echten externen Services auf.

Schlecht:


echte E-Mail senden
echten Payment-Provider aufrufen
in Production-S3 hochladen
echte Third-Party-API aufrufen

Besser:


Client mocken
Fake-Server nutzen
Sandbox-Umgebung vorsichtig nutzen
Testcontainers wo möglich

Merksatz:

Integrationstests sollen realistisch, aber sicher sein.


21. Externe Beans in @SpringBootTest mocken

Beispiel:


@SpringBootTest
class OrderIntegrationTest {

@MockitoBean
private PaymentClient paymentClient;

@Autowired
private OrderService orderService;

@Test
void createsOrderWhenPaymentSucceeds() {
when(paymentClient.charge(any()))
.thenReturn(new PaymentResult("OK"));

orderService.createOrder(...);

verify(paymentClient).charge(any());
}
}

Ältere Projekte nutzen vielleicht:


@MockBean

Merksatz:

In Integrationstests unsichere externe Systeme mocken.


22. Application Properties testen

Konfigurationsproperties:


@ConfigurationProperties(prefix = "app.storage")
public class StorageProperties {

private String bucket;
private int maxFileSizeMb;

// getters and setters
}

Test:


@SpringBootTest(properties = {
"app.storage.bucket=test-bucket",
"app.storage.max-file-size-mb=10"
})
class StoragePropertiesTest {

@Autowired
private StorageProperties properties;

@Test
void bindsStorageProperties() {
assertThat(properties.getBucket()).isEqualTo("test-bucket");
assertThat(properties.getMaxFileSizeMb()).isEqualTo(10);
}
}

Merksatz:

Integrationstests können Configuration Binding verifizieren.


23. Profile testen

Beispiel:


@SpringBootTest
@ActiveProfiles("test")
class ApplicationTest {
}

Das lädt:


application-test.yml

Nützlich für:


Test-Datenbank
deaktiviertes E-Mail-Versenden
Fake-API-URLs
Test-Feature-Flags
kleinere Connection Pools

Merksatz:

Nutze Test-Profile für test-spezifische Konfiguration.


24. Security in Integrationstests testen

Beispiel:


@SpringBootTest
@AutoConfigureMockMvc
class SecurityIntegrationTest {

@Autowired
private MockMvc mockMvc;

@Test
void anonymousCannotAccessTasks() throws Exception {
mockMvc.perform(get("/api/tasks"))
.andExpect(status().isUnauthorized());
}

@Test
@WithMockUser(authorities = "TASK_READ")
void userWithReadAuthorityCanAccessTasks() throws Exception {
mockMvc.perform(get("/api/tasks"))
.andExpect(status().isOk());
}
}

Das prüft echte Security-Konfiguration plus MVC-Flow.

Merksatz:

Integrationstests können echte Security-Regeln verifizieren.


25. CSRF in Integrationstests testen

Wenn CSRF aktiviert ist:


@Test
@WithMockUser(authorities = "TASK_WRITE")
void postWithoutCsrfIsForbidden() throws Exception {
mockMvc.perform(post("/api/tasks")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"title":"Task A"}
"""))
.andExpect(status().isForbidden());
}

Mit CSRF:


@Test
@WithMockUser(authorities = "TASK_WRITE")
void postWithCsrfIsAllowed() throws Exception {
mockMvc.perform(post("/api/tasks")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content("""
{"title":"Task A"}
"""))
.andExpect(status().isCreated());
}

Merksatz:

Wenn CSRF aktiviert ist, brauchen unsichere Methoden CSRF auch in Integrationstests.


26. JWT-Integration testen

Für Resource-Server-Tests:


@Test
void jwtWithReadScopeCanAccessTasks() throws Exception {
mockMvc.perform(get("/api/tasks")
.with(jwt().authorities(
new SimpleGrantedAuthority("SCOPE_task:read")
)))
.andExpect(status().isOk());
}

Das vermeidet die Erzeugung eines echten JWT.

Es testet:


Spring-Security-Authorization mit gemockter JWT-Authentication

Merksatz:

Nutze jwt(), um Resource-Server-Authorization-Regeln zu testen.


27. Was reicht für die Spring-Professional-Prüfung?

Für die Prüfung: Konzepte verstehen, nicht jedes Tool-Detail auswendig lernen.

Du solltest wissen:


Unit-Test vs. Integrationstest
Test-Pyramide
Rolle von JUnit
Rolle von AssertJ
Rolle von Mockito
Rolle von @MockBean / @MockitoBean
@SpringBootTest
@WebMvcTest
@DataJpaTest
MockMvc
TestEntityManager
Test-Slices
Test-Profile
Test-Properties
Transaktions-Rollback
@DirtiesContext
Security-Testing-Grundlagen
CSRF in Tests
wann Testcontainers nutzen

Merksatz:

Für die Prüfung: wissen, wann und warum du jeden Testtyp nutzt.


28. Entscheidungstabelle Testing für die Prüfung

Zu testenBeste Wahl
Reine Business-LogikUnit-Test
Service mit gemocktem RepositoryUnit-Test + Mockito
Controller Request/Response@WebMvcTest + MockMvc
Validation liefert 400@WebMvcTest
Error-Response von @ControllerAdvice@WebMvcTest
Repository-Query@DataJpaTest
Entity-Relationship-Mapping@DataJpaTest
Datenbank-Constraint@DataJpaTest + flush()
Vollständiger App-Context startet@SpringBootTest
Controller + Service + Repository@SpringBootTest + MockMvc
Echter HTTP-Server@SpringBootTest(RANDOM_PORT)
PostgreSQL-spezifisches SQLTestcontainers PostgreSQL
Security-Endpoint-RegelMockMvc + spring-security-test
Method SecuritySpring-Test + @WithMockUser

Merksatz:

Wähle den kleinsten Test, der das Verhalten beweist.


29. Abschließender Testing-Mock-Exam

Frage 1

Was ist ein Unit-Test?

A. Test einer Klasse ohne Spring B. Test des vollständigen Application Context C. Test nur des Datenbankschemas D. Manueller Test des Production-Servers

Antwort:


A

Frage 2

Was macht @SpringBootTest?

A. Lädt den vollständigen Spring-Boot-Application-Context B. Lädt nur JPA-Repositories C. Lädt nur einen Controller D. Deaktiviert Spring

Antwort:


A

Frage 3

Was testet @WebMvcTest?

A. MVC-/Controller-Slice B. Nur vollständige Datenbank C. Nur Kafka D. Nur Flyway

Antwort:


A

Frage 4

Was testet @DataJpaTest?

A. JPA-Entities und Repositories B. Nur REST-Controller C. Nur Security-Filter D. Nur externe APIs

Antwort:


A

Frage 5

Wofür wird MockMvc genutzt?

A. MVC-Requests ohne echten Server testen B. PostgreSQL starten C. JWT-Signaturen erstellen D. Flyway manuell ausführen

Antwort:


A

Frage 6

Wofür wird TestEntityManager genutzt?

A. Entities in JPA-Tests persistieren, flushen, clearen und finden B. CSS testen C. Mock-HTTP-User erstellen D. REST-Calls ausführen

Antwort:


A

Frage 7

Warum flush() in einem Repository-Test?

A. Um SQL-/Datenbank-Constraint-Ausführung zu erzwingen B. Um Spring Security zu deaktivieren C. Um einen Mock zu erstellen D. Um Webserver zu starten

Antwort:


A

Frage 8

Warum clear() in einem Repository-Test?

A. Um nicht nur aus dem Persistence-Context-Cache zu lesen B. Um den Application Context zu löschen C. Um JPA zu deaktivieren D. Um HTTP-Header zu entfernen

Antwort:


A

Frage 9

Was macht @MockBean oder @MockitoBean?

A. Ersetzt einen Spring-Bean durch einen Mockito-Mock B. Erstellt eine Datenbanktabelle C. Startet einen Docker-Container D. Aktiviert Transaktionen

Antwort:


A

Frage 10

Wofür ist Testcontainers nützlich?

A. Echte Infrastruktur wie PostgreSQL in Docker während Tests B. Nur Java-Methoden mocken C. REST-Controller erstellen D. Tests deaktivieren

Antwort:


A

Frage 11

Was ist das Standard-Rollback-Verhalten für transaktionale Spring-Tests?

A. Standardmäßig Rollback B. Immer standardmäßig Commit C. Application Context löschen D. Repositories deaktivieren

Antwort:


A

Frage 12

Wofür wird @DirtiesContext genutzt?

A. Spring mitteilen, den Test-Context nicht wiederzuverwenden B. Nur Datenbankzeilen bereinigen C. JSON erstellen D. Controller mocken

Antwort:


A

Frage 13

Wann solltest du @SpringBootTest statt @WebMvcTest nutzen?

A. Wenn du mehrere Layer oder den vollständigen App-Context brauchst B. Wenn du nur Request-Validation testest C. Wenn du nur eine reine Java-Methode testest D. Nie

Antwort:


A

Frage 14

Wann solltest du @DataJpaTest nutzen?

A. Um Repository-Queries und Entity-Mappings zu testen B. Um React-Komponenten zu testen C. Um nur Controller-JSON zu testen D. Um externen E-Mail-Provider zu testen

Antwort:


A

Frage 15

Was ist der beste Test für reine Berechnungslogik?

A. Unit-Test B. @SpringBootTest C. @DataJpaTest D. Echter HTTP-Test

Antwort:


A

Frage 16

Was ist der beste Test für Controller-Validation?

A. @WebMvcTest B. @DataJpaTest C. Manueller Datenbanktest D. Nur Testcontainers

Antwort:


A

Frage 17

Was ist der beste Test für eine Custom-Repository-Query?

A. @DataJpaTest B. Einfacher Unit-Test mit gemocktem Repository C. CSS-Test D. Nur Controller-Test

Antwort:


A

Frage 18

Was ist der beste Test für vollständigen Controller-Service-Repository-Flow?

A. @SpringBootTest B. Nur einfacher Unit-Test C. Nur @JsonTest D. Kein Test

Antwort:


A

Frage 19

Was macht .with(csrf())?

A. Fügt CSRF-Token zum MockMvc-Request hinzu B. Fügt JWT-Claim hinzu C. Startet Datenbank D. Deaktiviert Validation

Antwort:


A

Frage 20

Was macht @WithMockUser?

A. Fügt gemockten authentifizierten User zum Security-Context hinzu B. Erstellt echten Datenbank-User C. Startet echten Browser D. Deaktiviert Security

Antwort:


A

30. Abschließende Prüfungsfallen

Falle 1

Nutze nicht @SpringBootTest für jeden Test.

Nutze kleinere Tests, wenn möglich.


Falle 2

@WebMvcTest testet kein echtes Service-/Datenbank-Verhalten.

Es testet den Web-Layer.


Falle 3

@DataJpaTest testet keine Controller.

Es testet JPA.


Falle 4

Ein gemocktes Repository beweist nicht, dass Repository-SQL funktioniert.

Es hilft nur beim Testen der Service-Logik.


Falle 5

@MockBean / @MockitoBean ist für Spring-Tests.

Einfache Unit-Tests nutzen Mockito mock() oder @Mock.


Falle 6

POST-/PUT-/PATCH-/DELETE-Tests brauchen vielleicht CSRF.


Falle 7

Validation braucht @Valid.


Falle 8

Repository-Constraint-Tests brauchen oft flush().


Falle 9

Repository-Tests brauchen vielleicht clear(), um gecachte Entities zu vermeiden.


Falle 10

H2 ist nicht immer dasselbe wie PostgreSQL.


Falle 11

Testcontainers ist nützlich, wenn Datenbank-Realismus wichtig ist.


Falle 12

@DirtiesContext kann die Test-Suite verlangsamen.


Falle 13

Integrationstests brauchen eine Cleanup-Strategie.


Falle 14

Rufe in automatisierten Tests keine echten externen Production-Services auf.


Falle 15

Wähle den kleinsten Test, der das Verhalten beweist.


31. Abschließende Testing-Checkliste für die Spring-Professional-Prüfung

Du bist bereit für Testing-Fragen, wenn du erklären kannst:


[ ] Was ein Unit-Test ist.
[ ] Warum Unit-Tests Spring nicht starten sollten.
[ ] Was JUnit macht.
[ ] Was AssertJ macht.
[ ] Was Mockito macht.
[ ] Was Mocks und Stubs sind.
[ ] Was @MockBean / @MockitoBean macht.
[ ] Was @SpringBootTest macht.
[ ] Was @WebMvcTest macht.
[ ] Was @DataJpaTest macht.
[ ] Was MockMvc macht.
[ ] Was TestEntityManager macht.
[ ] Warum flush() nützlich ist.
[ ] Warum clear() nützlich ist.
[ ] Was Test-Slices sind.
[ ] Wann Slice-Tests nutzen.
[ ] Wann vollständige Integrationstests nutzen.
[ ] Was Test-Profile sind.
[ ] Was Test-Properties sind.
[ ] Was @DirtiesContext macht.
[ ] Wie transaktionaler Rollback in Tests funktioniert.
[ ] Wie man Controller-Validation testet.
[ ] Wie man Repository-Queries testet.
[ ] Wie man gesicherte Endpoints testet.
[ ] Warum POST-Tests csrf() brauchen können.
[ ] Was Testcontainers ist.
[ ] Warum H2 sich von PostgreSQL unterscheiden kann.
[ ] Warum Tests unabhängig sein sollten.
[ ] Warum Tests deterministisch sein sollten.
[ ] Wie man den kleinsten nützlichen Test wählt.

32. Abschließende Zusammenfassung

Testing in Spring Boot hat mehrere Ebenen.

Die Hauptebenen sind:


Unit-Tests
Web-Slice-Tests
JPA-Slice-Tests
Integrationstests

Die Hauptregel ist:


Wähle den kleinsten Test, der das Verhalten beweist.

Für Service-Logik:


Nutze Unit-Tests mit JUnit, AssertJ und Mockito.

Für Controller:


Nutze @WebMvcTest und MockMvc.

Für Repositories:


Nutze @DataJpaTest und TestEntityManager.

Für vollständiges Anwendungsverhalten:


Nutze @SpringBootTest.

Für echtes Datenbankverhalten:


Nutze Testcontainers, wenn H2 nicht realistisch genug ist.

Für die Prüfung:


Unit-Test = eine Klasse, ohne Spring.
WebMvcTest = Controller-Slice.
DataJpaTest = Repository-Slice.
SpringBootTest = vollständiger Application Context.
MockMvc = HTTP-ähnlicher MVC-Test ohne echten Server.
Testcontainers = echte Infrastruktur in Docker.

Das reicht als Testing-Wissen für eine solide Spring-Professional-Prüfungsvorbereitung.