Spring Boot Test Slices: @WebMvcTest and @DataJpaTest
Use @WebMvcTest to test controllers in isolation and @DataJpaTest for repository layer testing.
Spring Boot Test Slices: @WebMvcTest and @DataJpaTest is a free Java Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Are Test Slices?
Test slices load only the relevant portion of the Spring context for a specific layer. They are faster than @SpringBootTest (which loads everything) and isolate the layer under test.
@WebMvcTest: Controller Layer Only
@WebMvcTest(UserController.class) loads only the web layer: controllers, filters, security config, and Jackson. Services and repositories must be mocked with @MockBean.
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired MockMvc mockMvc;
@MockBean UserService userService;
@Test
void get_user_returns_200() throws Exception {
given(userService.findById(1L)).willReturn(new UserDto(1L, "Alice"));
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}MockMvc Request Building
Build requests with MockMvcRequestBuilders. Set headers, content type, and request body for POST/PUT tests.
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"Bob","email":"bob@example.com"}"""))
.andExpect(status().isCreated())
.andExpect(header().exists("Location"));Testing Validation in @WebMvcTest
Invalid request bodies trigger MethodArgumentNotValidException. Assert on the 400 status and the error response body.
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"","email":"bad"}"""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors.name").exists());@DataJpaTest: Repository Layer Only
@DataJpaTest loads JPA repositories, the embedded H2 database, Hibernate, and a TestEntityManager. Other beans (services, web) are not loaded.
@DataJpaTest
class UserRepositoryTest {
@Autowired UserRepository repo;
@Autowired TestEntityManager em;
@Test
void find_by_email() {
em.persist(new User("Alice", "alice@example.com"));
em.flush();
Optional<User> found = repo.findByEmail("alice@example.com");
assertTrue(found.isPresent());
}
}TestEntityManager
TestEntityManager wraps EntityManager with convenience methods: persist(), flush(), find(), persistAndFlush().
User saved = em.persistAndFlush(new User("Bob", "bob@example.com"));
assertNotNull(saved.getId());
em.clear(); // detach all to force a real DB read
User fromDb = repo.findById(saved.getId()).orElseThrow();
assertEquals("Bob", fromDb.getName());@DataJpaTest Rollback
Each test runs in a transaction that is rolled back after the test by default. Data does not persist between tests — ensuring test isolation without manual cleanup.
@DataJpaTest // each @Test is rolled back automatically
class OrderRepositoryTest {
@Test @Transactional
void count_orders_is_zero_by_default() {
assertEquals(0, orderRepo.count());
}
}Replacing H2 with Real DB in @DataJpaTest
Use @AutoConfigureTestDatabase(replace = Replace.NONE) to run @DataJpaTest against the real database configured in application.properties instead of H2.
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class ProductRepositoryTest {
// Uses the configured PostgreSQL, not H2
}@JsonTest: JSON Serialization Only
@JsonTest loads Jackson configuration. Use JacksonTester to verify that objects serialize and deserialize as expected.
@JsonTest
class UserDtoJsonTest {
@Autowired JacksonTester<UserDto> json;
@Test
void serializes_correctly() throws Exception {
UserDto dto = new UserDto(1L, "Alice", "alice@example.com");
assertThat(json.write(dto)).hasJsonPathStringValue("$.email");
}
}@RestClientTest: REST Client Layer
@RestClientTest tests RestTemplate or WebClient-based HTTP clients. It configures a MockRestServiceServer to mock HTTP responses.
@RestClientTest(WeatherClient.class)
class WeatherClientTest {
@Autowired WeatherClient client;
@Autowired MockRestServiceServer server;
@Test
void fetches_weather() {
server.expect(requestTo("/api/weather")).andRespond(withSuccess("""{"temp":22}""", APPLICATION_JSON));
Weather w = client.getWeather("Istanbul");
assertEquals(22, w.getTemp());
}
}Combining Slices with @Import
Slices exclude many beans by design. Use @Import(SomeConfig.class) to add specific configuration classes that the slice needs.
@WebMvcTest(UserController.class)
@Import(SecurityConfig.class) // load security for auth tests
class SecuredControllerTest { ... }Quick Check
What does @DataJpaTest use as the default database?
Recap
@WebMvcTest tests the controller layer with MockMvc; mock services with @MockBean. @DataJpaTest tests repositories with TestEntityManager and auto-rollback. Use Replace.NONE for real DB. @JsonTest for serialization, @RestClientTest for HTTP clients.
Frequently asked questions
Is the “Spring Boot Test Slices: @WebMvcTest and @DataJpaTest” lesson free?
Yes — the full text of “Spring Boot Test Slices: @WebMvcTest and @DataJpaTest” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Spring Boot Test Slices: @WebMvcTest and @DataJpaTest”?
Use @WebMvcTest to test controllers in isolation and @DataJpaTest for repository layer testing. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Spring Boot Test Slices: @WebMvcTest and @DataJpaTest” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Parameterized Tests with @CsvSource and @MethodSource
- Mockito Advanced: Argument Captors and Spies
- Spring Boot Test Slices: @WebMvcTest and @DataJpaTest
- Testcontainers: Real Database Integration Tests