# @SpringBootTest and Test Slices — JUnit 5 & Mockito

Source: https://www.skillbyai.com/en/java-testing/s-slices

> Choose between full-context tests and focused slices, and replace beans with @MockitoBean.

## Load only what the test needs

Spring Boot tests can start the whole application context with **`@SpringBootTest`**, which is realistic but slow. **Test slices** load only part of it: **`@WebMvcTest`** loads the web layer (controllers, filters, JSON conversion, validation) for testing controllers with MockMvc; **`@DataJpaTest`** loads JPA components (entities, repositories, transactions, Flyway) and rolls back after each test; **`@JsonTest`** focuses on JSON serialisation; **`@RestClientTest`** tests HTTP clients against a mock server. Within a Spring test, replace a bean with a Mockito mock using **`@MockitoBean`** (introduced in Spring Framework 6.2 / Spring Boot 3.4, replacing the now-deprecated `@MockBean`) or wrap it with `@MockitoSpyBean`. Spring caches application contexts between tests with the same configuration, so keep configurations consistent; each distinct combination of mocked beans creates a new context and slows the suite. Use plain JUnit and Mockito, **without Spring**, for business logic: those tests run in milliseconds.

## Full context versus slices

@SpringBootTest loads everything; slices load just the layer under test.

![A full stack of layered blocks on the left; on the right, the same stack with only one layer highlighted and the rest faded.](assets/figures/java-testing/section-7-map.svg) — Figure 7.1 — A full application context compared with a test slice.

## A controller slice test with a mocked service

Only the web layer starts; the service is a Mockito mock.

```java
@WebMvcTest(OrderController.class)
class OrderControllerTest {

    @Autowired MockMvc mvc;

    @MockitoBean                                // Spring Framework 6.2+ (replaces @MockBean)
    OrderService orderService;

    @Test
    void returnsOrderSummary() throws Exception {
        given(orderService.summary(42L))
            .willReturn(new OrderSummary(42L, "Asha", new BigDecimal("499.00"), OrderStatus.PAID));

        mvc.perform(get("/api/orders/42").accept(MediaType.APPLICATION_JSON))
           .andExpect(status().isOk())
           .andExpect(jsonPath("$.id").value(42))
           .andExpect(jsonPath("$.customerName").value("Asha"))
           .andExpect(jsonPath("$.status").value("PAID"));
    }

    @Test
    void rejectsInvalidQuantity() throws Exception {
        mvc.perform(post("/api/orders")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"sku\":\"pen\",\"quantity\":0}"))
           .andExpect(status().isBadRequest());
        then(orderService).shouldHaveNoInteractions();
    }
}
```

## Not every test needs Spring

If a test does not need dependency injection, web handling or persistence, write it as a plain JUnit test. A suite where every test starts Spring takes minutes instead of seconds.

**Quiz:** Which annotation loads only the web layer for testing a controller with MockMvc?

- [x] @WebMvcTest
- [ ] @SpringBootTest
- [ ] @DataJpaTest
- [ ] @JsonTest

*Answer:* @WebMvcTest. @WebMvcTest configures just the MVC infrastructure and the specified controllers.
