Real World Example

Tests Guard Every Release

Teams at Flipkart, PhonePe or any bank run thousands of tests on every pull request. A change that breaks the Product API (wrong status code, renamed JSON field, failing validation) is caught by CI before it reaches users. A typical ShopEase split:

Class under testTest typeChecks
ProductServiceJUnit + Mockitoduplicate SKU, stock rules, mapping
ProductController@WebMvcTestall CRUD URLs, 201/204/404, validation errors
ProductRepository@DataJpaTestderived queries, paging
Whole app@SpringBootTest + Testcontainerscreate → get → update → delete on PostgreSQL

ShopEase: CRUD Lifecycle Test

@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class ProductCrudIT {

    @Container @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Autowired MockMvc mvc;

    @Test
    void fullLifecycle() throws Exception {
        String location = mvc.perform(post("/api/products").contentType(MediaType.APPLICATION_JSON)
                        .content("""
                            {"sku":"BOO-3001","name":"Effective Java","description":"3rd edition",
                             "price":699.00,"stock":25,"category":"Books"}
                            """))
                .andExpect(status().isCreated())
                .andReturn().getResponse().getHeader("Location");

        mvc.perform(get(location)).andExpect(status().isOk())
           .andExpect(jsonPath("$.name").value("Effective Java"));

        mvc.perform(put(location).contentType(MediaType.APPLICATION_JSON)
                        .content("""
                            {"sku":"BOO-3001","name":"Effective Java","description":"3rd edition",
                             "price":649.00,"stock":20,"category":"Books"}
                            """))
           .andExpect(jsonPath("$.price").value(649.00));

        mvc.perform(delete(location)).andExpect(status().isNoContent());
        mvc.perform(get(location)).andExpect(status().isNotFound());
    }
}

Example

Run everything the way CI does:

./mvnw clean verify

Example output

[INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0   (unit + web tests, surefire)
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0   (*IT classes, failsafe)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] Total time:  41.208 s

Exercise: Write a @WebMvcTest test that checks DELETE /api/products/5 returns 204 and calls service.delete(5L).

Show answer
@Test
void deleteReturns204() throws Exception {
    mockMvc.perform(delete("/api/products/5"))
           .andExpect(status().isNoContent());
    verify(service).delete(5L);
}