← Java

Java · 15 / 18

JUnit, semantische PDF-Tests und Testcontainers

Du prüfst den Inhalt eines echten PDFs und wählst Tests nach der zu beweisenden Garantie.

  • Mittel
  • Fortgeschritten
  • 45 min

Voraussetzungen: PostgreSQL, JPA und Flyway verstehen

Ein Test muss eine beobachtbare Garantie kontrollieren. Bei einem PDF sind das etwa Seitenzahl, Feldwert oder enthaltene Dateien eines Archivs. Ein Vergleich aller Bytes kann an Metadaten scheitern und trotzdem wenig über den fachlichen Inhalt aussagen. Dieses Tutorial ergänzt den PDF-Generator aus Tutorial 11 um einen semantischen Test. Anschließend unterscheiden wir Unit-, Integrations- und Datenbankvertragstests.

01Den Testaufbau ergänzen

Verwende Main.java aus Tutorial 11. Die neue pom.xml ergänzt JUnit. Speichere den Test unter src/test/java/tutorial/PdfTest.java. Maven Surefire entdeckt die Testklasse und führt sie beim test-Schritt aus.

pom.xml · xmlDatei öffnen
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>example</groupId><artifactId>learning</artifactId><version>1.0</version>
  <properties><maven.compiler.release>21</maven.compiler.release><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties>
  <dependencies><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.8</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-csv</artifactId><version>1.14.1</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.13.4</version><scope>test</scope></dependency></dependencies>
  <build><plugins>
    <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.14.1</version></plugin>
    <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.5.3</version></plugin>
  </plugins></build>
</project>

Starten / prüfen

mvn package dependency:copy-dependencies
java -cp "target/classes:target/dependency/*" tutorial.Main

02Ein wirklich erzeugtes PDF lesen

Der Test ruft den Generator auf und lädt danach result.pdf mit PDFBox. Er prüft Seitenzahl und den Wert des benannten Feldes. finally entfernt nur die vom Lernprogramm erzeugte Datei. Verwende dafür einen getrennten Lernordner.

src/test/java/tutorial/PdfTest.java · javaDatei öffnen
package tutorial;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.pdfbox.Loader;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class PdfTest {
  @Test void recipientIsPreservedInGeneratedPdf() throws Exception {
    try {
      Main.main(new String[0]);
      try (var document = Loader.loadPDF(Path.of("result.pdf").toFile())) {
        assertEquals(1, document.getNumberOfPages());
        assertEquals("Ada", document.getDocumentCatalog().getAcroForm()
          .getField("recipient").getValueAsString());
      }
    } finally { Files.deleteIfExists(Path.of("result.pdf")); }
  }
}

Starten / prüfen

mvn test

03Eine falsche Änderung erkennen

Ändere Ada im Generator zu Lin. Der Test muss am erwarteten Feldwert scheitern. Setze die Änderung zurück. Das zeigt, welche konkrete fachliche Aussage der Test schützt.

04Die Testarten passend ergänzen

Unit-Tests prüfen Zustandsregeln ohne Infrastruktur. HTTP-Tests prüfen den vollständigen Upload- und Downloadablauf. Testcontainers startet eine echte PostgreSQL-Instanz für Adapterverträge. Fehlt Docker, muss ein solcher Test als übersprungen erkennbar sein, statt als bestandener Datenbanknachweis zu gelten.

Erwartetes Ergebnis

mvn test bestätigt eine Seite und recipient = Ada. Der Test erkennt einen absichtlich geänderten Empfängernamen.

Deine Übung

Prüfe zusätzlich, dass das Feld recipient existiert, bevor du seinen Wert liest.

Lösung mit Erklärung anzeigen

Speichere das Feld in einer Variablen und verwende assertNotNull mit einer verständlichen Meldung. Danach prüft assertEquals den Inhalt. Ein fehlendes Feld und ein falscher Wert werden dadurch als unterschiedliche Ursachen sichtbar.

Projektbezug und Quellen

Das Beispiel ist zum Lernen vereinfacht. Die verlinkte Codeversion zeigt die Anwendung im Projekt und die dortigen Prüfungen.