The Spring Test Stack
What spring-boot-starter-test gives you, and when to load the whole context with @SpringBootTest versus a thin slice.
On this page
You've built a real application - a secured, database-backed API. How do you know it works, and stays working as you change it? Tests. Spring Boot ships a rich testing toolkit, and the key skill is choosing the right kind of test for each job.
What you already have
Every Boot project includes spring-boot-starter-test, which bundles the essentials:
- JUnit 5 — the test framework (
@Test,@BeforeEach). - AssertJ — fluent assertions (
assertThat(x).isEqualTo(y)). - Mockito — creating mock objects.
- Spring's test support — booting contexts and test slices.
You've already used the first three for plain unit tests. Now you'll add Spring's part.
The spectrum: unit to full context
Not every test should start Spring. There's a spectrum, from "no framework at all" to "the whole application," trading speed for realism:
Loads only the web layer + MockMvc. Services/repositories are mocked (@MockitoBean). Tests routing, validation, JSON, status codes.
- Plain unit test — no Spring;
newthe class and pass mocks. Milliseconds. Best for pure logic (BookVault'sBookServicerules). - Slice tests (
@WebMvcTest,@DataJpaTest) — start just one layer. Fast, and focused on that layer. @SpringBootTest— start the entire application context. The most realistic and the slowest; reserve it for end-to-end checks.
A mechanic doesn't run the whole car on a rolling road to check a single spark plug - they test the plug on the bench. But to verify the car actually drives, they do take it out on the road. Tests are the same: bench-test a unit in isolation when you can (fast, precise), and only run the whole application when you specifically need to prove the pieces work together. Matching the test's scope to the question keeps your suite fast.
The golden rule
Prefer the smallest test that answers your question. Testing a validation rule?
A slice or unit test. Verifying a SQL query? @DataJpaTest. Confirming security rules
across the real stack? @SpringBootTest. Reaching for @SpringBootTest for everything
gives you a slow suite that developers stop running - the opposite of helpful.
For each, pick the lightest test type that fits: plain unit, @WebMvcTest, @DataJpaTest, or @SpringBootTest.
BookServicerejects a duplicate ISBN.GET /api/books/{isbn}returns 404 for an unknown ISBN.BookRepository.findByAuthorIgnoreCase(...)returns the right rows.- A LIBRARIAN token can POST a book but a MEMBER token gets 403 (end to end).
What is the trade-off @SpringBootTest makes compared with a slice or unit test?
Key takeaways
- spring-boot-starter-test bundles JUnit 5, AssertJ, Mockito, and Spring's test support.
- Tests span a spectrum from plain unit (no Spring) through slices (@WebMvcTest, @DataJpaTest) to @SpringBootTest (full context), trading speed for realism.
- Prefer the smallest test that answers your question; reserve @SpringBootTest for end-to-end checks.
- An over-reliance on @SpringBootTest makes the suite slow, so developers run it less - defeating the point.
- Match the test's scope to the question, like choosing the right zoom level.