Integration Testing

Site Admin · 11 Sep 2026 · 8 views

Integration Testing

Where Units Meet

Unit tests prove each piece works alone. Integration tests prove the pieces work together: a service class writing to a real (or near-real) database, an API controller calling the service layer, a repository executing real SQL. Bugs live at those boundaries, and unit tests cannot catch them.

What Integration Tests Cover

  • Persistence: rows written to the database and read back correctly.
  • Contracts: the format exchanged between components matches on both sides.
  • Configuration: connection strings, profiles, and startup wiring are valid.
  • Third-party clients: requests to external services carry the right shape.

Databases in Tests

Real logic deserves real infrastructure, but not a fragile shared database. The established pattern is a test database, created fresh, migrated, and cleaned before and after each test class:

@SpringBootTest
@Testcontainers
class CustomerRepositoryTest {

    @Test
    void findsCustomerByEmail() {
        Customer found = repository.findByEmail("ada@example.com");
        assertNotNull(found);
    }
}

Testcontainers starts a disposable database in Docker for the test run, giving the fidelity of a real database without polluting the shared environment. The setup lets tests run identically in CI on any machine.

Keep the Suite Honest

Integration tests are slower than unit tests, so keep them focused: verify the journey between two real boundaries, not behavior already proven by unit tests. Some projects mark integration tests so they run in a separate CI stage, keeping the fast feedback loop for unit tests intact.

Common Failures

Integration tests catch a whole class of problems unit tests miss: schema drift between the code's expectations and the migration files, case and collation differences, transaction boundaries that do not commit, and caching layers returning stale values. When such a failure appears, it is a design lesson, not a nuisance.

Key Points

  • Integration tests verify components working together across real boundaries.
  • Cover persistence, contracts, configuration, and external clients.
  • Use a disposable real database via Testcontainers for fidelity.
  • Keep integration tests focused and slower than unit tests.
  • Failures often reveal schema, transaction, or configuration bugs.
Share this post:

Comments (0)

Please login or register to comment.