Skip to content
AyoKoding

Test Slices

Why Test Slices Matter

Spring Boot test slices (@WebMvcTest, @DataJpaTest) load minimal ApplicationContext for specific layers, reducing test startup from 10+ seconds (@SpringBootTest full context) to <2 seconds (slice). In production test suites with 1000+ tests, slice testing saves 2+ hours of CI/CD time by loading only required beans (controllers without services, repositories without web layer).

Solution: @WebMvcTest for controllers, @DataJpaTest for repositories.

@WebMvcTest(DonationController.class)
// => Only loads web layer: DonationController + Spring MVC infrastructure
// => NO services, repositories, or database
class DonationControllerTest {
 
    @Autowired
    private MockMvc mockMvc;  // => Test Spring MVC without HTTP
 
    @MockBean  // => Mock service (not loaded in web slice)
    private DonationService donationService;
 
    @Test
    void shouldReturnDonation() throws Exception {
        when(donationService.findById(1L))
            .thenReturn(new DonationResponse(1L, BigDecimal.valueOf(1000)));
 
        mockMvc.perform(get("/api/donations/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id").value(1))
            .andExpect(jsonPath("$.amount").value(1000));
    }
}

@DataJpaTest (repository slice):

@DataJpaTest  // => Only loads JPA infrastructure: repositories + embedded database
// => NO controllers, services, or web layer
class DonationRepositoryTest {
 
    @Autowired
    private DonationRepository repository;  // => Real repository
 
    @Autowired
    private TestEntityManager entityManager;  // => Test helper for JPA
 
    @Test
    void shouldFindByDonorName() {
        ZakatDonation donation = new ZakatDonation();
        donation.setDonorName("Ahmad");
        donation.setAmount(BigDecimal.valueOf(1000));
        entityManager.persist(donation);
 
        List<ZakatDonation> found = repository.findByDonorName("Ahmad");
 
        assertThat(found).hasSize(1);
        assertThat(found.get(0).getAmount()).isEqualTo(BigDecimal.valueOf(1000));
    }
}

Performance comparison:

Test TypeStartup TimeBeans LoadedUse Case
@SpringBootTest10-15sAll (~500)End-to-end integration
@WebMvcTest<2sWeb layer only (~50)Controller logic
@DataJpaTest<2sJPA layer only (~30)Repository queries

Trade-offs: Test slices for fast feedback (unit-like speed for integration tests). @SpringBootTest for critical flows.

Next Steps

Last updated February 5, 2026

Command Palette

Search for a command to run...