Return to site

🧪🗄️ The BEST Way to TEST your DATA Access Layer

Mocking repositories isn’t testing your database. Here’s what is.

🔸 TLDR

▪️ Unit tests are great for independent business logic.

▪️ Mocking repositories mostly tests interactions, not SQL behavior.

▪️ Integration tests validate the real database interaction.

▪️ Prefer the same database engine as production.

▪️ System integration tests go further by including the complete application and networking costs.

🔸 TRUTH

Mocking your repository can prove that your Java code calls the right method.

It cannot prove that your database behaves correctly.

That’s the key idea behind Vlad article: for a relational data access layer, integration testing gives you much more confidence than isolated unit tests.

🔸 1️⃣ MOCKING DOESN’T TEST THE DATABASE

when(
    postRepository.findTopN(
        any(Sort.class),
        eq(PAGE_SIZE)
    )
).thenReturn(pagedList);

This proves that ForumService interacts with the repository as expected. But filtering, sorting, generated SQL and database behavior remain completely mocked.

🔸 2️⃣ TEST THE REAL DATA ACCESS FLOW

PagedList<Post> topPage =
    forumService.firstLatestPosts(PAGE_SIZE);
assertEquals(POST_COUNT, topPage.getTotalSize());
assertEquals(Long.valueOf(50), topPage.get(0).getId());

Now the repository actually talks to the database, letting the test validate pagination, ordering and the behavior users will eventually depend on.

🔸 3️⃣ LOOK AT THE SQL THAT REALLY RUNS

ORDER BY
    p1_0.created_on DESC NULLS LAST,
p1_0.id DESC
OFFSET ? ROWS
FETCH FIRST ? ROWS ONLY

Integration testing lets you validate generated SQL, query counts, batching, N+1 problems and database-specific semantics; not merely Java method calls.

💡SQL visibility comes from Hibernate logging settings such as spring.jpa.show-sql.

🔸 IN-MEMORY DB OR REAL ENGINE?

The article recommends avoiding H2/HSQLDB as substitutes when production uses another engine.

A local database, Docker or Testcontainers lets you test against the actual PostgreSQL/MySQL/etc. engine used in production.

System integration testing then adds another missing variable: 🌐 networking and a production-like QA environment.

🔸 TAKEAWAYS

▪️ Mock business logic when isolation makes sense.

▪️ Don’t mock away the thing your persistence layer exists to integrate with.

▪️ Test queries against the production database engine.

▪️ Validate SQL, transactions, concurrency, batching and N+1 behavior.

▪️ Add system integration tests for the full production-like flow.

Your repository API may be Java.

Your actual persistence behavior lives in the database. 🗄️

#Java #Spring #SpringBoot #JPA #Hibernate #Testing #IntegrationTesting #Testcontainers #PostgreSQL #SoftwareEngineering

Go further with Java certification:

Java👇

Spring👇

SpringBook👇

JavaFullstackBook👇