17 · Tests and migrations / LESSON 86 OF 102
Integration tests and API contracts
Verify real wiring and persistence.
Before this lesson: Unit tests and test doubles
Understand the topic
@SpringBootTest creates the application context. Use a dedicated test database or disposable PostgreSQL/Testcontainers, never production. A test transaction rolls back data, but separate tests are needed when verifying real commit behavior.
API tests should assert status, headers, JSON, validation, ownership, and pagination. After adding security, supply the appropriate authentication and CSRF token. The service-level example below does not replace HTTP tests.
EXAMPLE · JAVA
src/test/java/com/example/tasks/TaskServiceTest.java
package com.example.tasks;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@Transactional
class TaskServiceTest {
@Autowired TaskService service;
@Autowired TaskRepository repository;
@Test void persistsNormalizedTitle() {
Task saved = service.create(" Learn tests ");
assertNotNull(saved.getId());
assertEquals("Learn tests",
repository.findById(saved.getId()).orElseThrow().getTitle());
}
}What to expect
With a test datasource/schema, Spring starts and persistence is exercised. The test transaction rolls back.
YOUR TURN
Put it into practice
- 01Test a missing ID.
- 02Add HTTP tests for 201, Location, 400, and 404.
- 03Verify two users cannot access each other’s resources.
Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.
UNDER THE HOOD
Build the mental model
Integration tests exercise the seams where individually correct components can disagree.
- 01Use the database engine you deploy when testing engine-specific behavior. An in-memory substitute may differ in SQL, constraints, and transaction semantics.
- 02Test rollback keeps test data isolated, but can hide behavior that occurs only on commit. Include a test that observes the committed state from a separate transaction when needed.
- 03HTTP tests cover serialization, routing, validation, and security filters that a direct service call bypasses.
A mistake worth avoiding
Never point integration tests at a production datasource.
DEBUGGING ROOM
Something broke. Where do you look?
Tests pass with an in-memory database but migrations fail on PostgreSQL.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
Does a direct service test prove the HTTP endpoint enforces CSRF?
BUILD IT YOURSELF
Build an end-to-end test slice
- 1.Start a disposable database.
- 2.Run migrations, create a user, and call authenticated endpoints.
- 3.Verify status, headers, JSON, and persisted rows.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
Which behavior exists only at commit or at the HTTP boundary?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
Explain unit, integration, and HTTP contract coverage.
Reading is separate from passing a knowledge check or completing a lab.