Loslegen
Javaneer
Zurück zur Stufe
Modul 5·Spring-Anwendungen testen

Daten-Slice-Tests mit @DataJpaTest

Repositories und Abfragen gegen eine echte (Test-)Datenbank testen, ohne den Rest der Anwendung.

14 Min. LesezeitFortgeschritten

Deutsche Übersetzung in Arbeit

Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.

Auf dieser Seite

Your repositories carry real logic - derived queries, JPQL, JOIN FETCH. A mock can't tell you whether findByAuthorIgnoreCaseOrderByTitleAsc actually returns the right rows in the right order; only a database can. @DataJpaTest starts just the JPA layer against a test database so you can verify queries for real, fast.

The slice

@DataJpaTest configures JPA, Hibernate, and your repositories - and nothing else (no web layer, no services, no security). It gives each test a fresh, isolated database and rolls back after every test, so tests never pollute each other.

@DataJpaTest
class BookRepositoryTest {

    @Autowired BookRepository repository;

    @Test
    void findsBooksByAuthorSortedByTitle() {
        repository.save(new Book("978-1", "Zebra", "Bloch", 1));
        repository.save(new Book("978-2", "Apple", "Bloch", 1));
        repository.save(new Book("978-3", "Other", "Gosling", 1));

        var books = repository.findByAuthorIgnoreCaseOrderByTitleAsc("bloch");

        assertThat(books).extracting(Book::getTitle).containsExactly("Apple", "Zebra");
    }
}

You saved real rows and ran a real query - the assertion proves the derived method's WHERE, ORDER BY, and case-insensitivity all work.

Each test starts clean and rolls back

@DataJpaTest wraps each test in a transaction that's rolled back at the end, so tests are isolated and repeatable - you never have to clean up data between them.

H2 now, the real engine later

By default @DataJpaTest uses an embedded database (H2). That's fast and fine for straightforward queries, but H2 isn't PostgreSQL - a native query or a database-specific feature can pass on H2 and fail in production. That gap is exactly what Testcontainers (next lesson) closes, by pointing the same slice at a real PostgreSQL container.

Test the plumbing with water, not a diagram

You can't verify a building's plumbing by reading the blueprint - you have to turn the water on and watch it flow through the actual pipes. Mocking a repository tests the blueprint; @DataJpaTest turns the water on. It runs your queries through a real JPA provider and a real (if lightweight) database, so you find leaks the diagram can't show.

What can only @DataJpaTest catch?

BookVault's LoanRepository.findActiveByMember uses a JPQL JOIN FETCH to load each loan's book and member. Why can a plain unit test with a mocked repository never verify this method works, and what would a @DataJpaTest prove that a mock cannot?

What does @DataJpaTest load and test?

Key takeaways

  • @DataJpaTest starts only the JPA layer and repositories against a test database - no web, service, or security.
  • It runs real queries against real rows, so it verifies derived methods, JPQL, ordering, and mappings a mock never could.
  • Each test is wrapped in a transaction and rolled back, keeping tests isolated and repeatable.
  • By default it uses embedded H2; database-specific behavior may differ from production.
  • Point the same slice at a real engine with Testcontainers to close the H2-vs-production gap.
War diese Lektion hilfreich?
Diese Seite auf GitHub bearbeiten