A test must check an observable guarantee. For a PDF, that may be page count, field value or archive contents. Comparing every byte can fail because of metadata while saying little about domain contents. This tutorial adds a semantic test to the generator from tutorial 11, then distinguishes unit, integration and database contract tests.
01Extend the test setup
Use Main.java from tutorial 11. The new pom.xml adds JUnit. Save the test at src/test/java/tutorial/PdfTest.java. Maven Surefire discovers the test class and runs it during test.
<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>
Run / check
mvn package dependency:copy-dependencies
java -cp "target/classes:target/dependency/*" tutorial.Main02Read an actually generated PDF
The test calls the generator and loads result.pdf using PDFBox. It checks page count and the named field’s value. finally removes only the file produced by the learning program. Use a separate learning directory.
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")); }
}
}
Run / check
mvn test03Detect an incorrect change
Change Ada in the generator to Lin. The test must fail on the expected field value. Restore the change. This shows which concrete domain statement the test protects.
04Add suitable kinds of tests
Unit tests check state rules without infrastructure. HTTP tests check the full upload and download workflow. Testcontainers starts a real PostgreSQL instance for adapter contracts. If Docker is missing, such a test must visibly be skipped rather than counted as passed database evidence.
mvn test confirms one page and recipient = Ada. The test detects a deliberately changed recipient name.
Your exercise
Also verify the recipient field exists before reading its value.
Show the solution and explanation
Store the field in a variable and use assertNotNull with a clear message. Then assertEquals checks its contents. A missing field and an incorrect value become distinguishable causes.
Project context and sources
The example is simplified for learning. The linked source version shows its use in the project and the checks applied there.