Working with Testing
1. Using @SpringBootTest for Integration Tests
Example: Integration test with MockMvc
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
class OrderApiIT {
@Autowired MockMvc mvc;
@Test void getOrder() throws Exception {
mvc.perform(get("/api/orders/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1));
}
}
| WebEnvironment | Description |
|---|---|
| MOCK (default) | Mock servlet, no real port |
| RANDOM_PORT | Real Tomcat, random port |
| DEFINED_PORT | Real Tomcat, configured port |
| NONE | No web environment |
2. Using @WebMvcTest for Controller Tests
Example: Slice test for controller layer
@WebMvcTest(OrderController.class)
class OrderControllerTests {
@Autowired MockMvc mvc;
@MockBean OrderService svc;
@Test void create() throws Exception {
when(svc.create(any())).thenReturn(new OrderDto(1L));
mvc.perform(post("/api/orders").contentType(MediaType.APPLICATION_JSON)
.content("{\"items\":[]}"))
.andExpect(status().isCreated());
}
}
3. Using @DataJpaTest for Repository Tests
Example: Repository test against real database
@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE) // use real DB
class OrderRepositoryTests {
@Autowired OrderRepository repo;
@Autowired TestEntityManager em;
@Test void findsByReference() {
em.persist(new Order("REF-1"));
assertThat(repo.findByReference("REF-1")).isPresent();
}
}
4. Using @MockBean for Mocking Dependencies
| Annotation | Use |
|---|---|
@MockBean |
Replace bean with Mockito mock |
@SpyBean |
Wrap real bean as spy |
Spring 6.2+ @MockitoBean |
Replacement for @MockBean |
5. Using MockMvc for REST API Testing
| Method | Use |
|---|---|
perform(get/post/...) |
Issue request |
andExpect(status().isOk()) |
Status assertion |
andExpect(jsonPath("$.field")) |
JSON path assertion |
andExpect(content().json(...)) |
Full JSON match |
andDo(print()) |
Debug output |
andReturn().getResponse() |
Capture response |
6. Testing with TestRestTemplate
Example: HTTP client integration test
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class HttpClientIT {
@Autowired TestRestTemplate rest;
@Test void list() {
ResponseEntity<OrderDto[]> resp = rest.getForEntity("/api/orders", OrderDto[].class);
assertEquals(HttpStatus.OK, resp.getStatusCode());
}
}
7. Using @Sql for Test Data Setup
Example: Load and clean SQL test data
@SpringBootTest
@Sql(scripts = "/test-data/orders.sql",
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/test-data/cleanup.sql",
executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
class OrderTests { /* … */ }
8. Configuring Test Properties (@TestPropertySource)
Example: Override properties in test
@SpringBootTest
@TestPropertySource(properties = {
"app.feature.x.enabled=true",
"spring.datasource.url=jdbc:h2:mem:test"
})
class FeatureXTests { /* … */ }
// Or @SpringBootTest(properties = {...})
9. Using Test Slices
| Slice | Loads |
|---|---|
@WebMvcTest |
MVC infrastructure + controller |
@WebFluxTest |
WebFlux infrastructure |
@DataJpaTest |
JPA + embedded DB + transactions |
@DataR2dbcTest |
R2DBC reactive |
@DataMongoTest |
MongoDB |
@DataRedisTest |
Redis |
@JsonTest |
Jackson/Gson serializers |
@RestClientTest |
RestClient + MockRestServiceServer |
@JdbcTest |
JDBC + embedded DB |
10. Testing Security with @WithMockUser
Example: Security test with mock user and JWT
@Test
@WithMockUser(username="alice", roles={"ADMIN"})
void adminOnly() throws Exception { /* … */ }
@Test
@WithAnonymousUser
void requiresAuth() throws Exception { /* … */ }
@Test
void jwt() throws Exception {
mvc.perform(get("/api/me").with(jwt().jwt(j -> j.subject("123"))));
}
11. Writing Unit Tests with JUnit 5 and Mockito
Example: Unit test with Mockito mocks
@ExtendWith(MockitoExtension.class)
class OrderServiceTests {
@Mock OrderRepository repo;
@Mock PaymentClient pay;
@InjectMocks OrderService service;
@Test void placesOrder() {
when(repo.save(any())).thenAnswer(a -> a.getArgument(0));
Order o = service.place(new NewOrder(/* … */));
verify(pay).charge(any());
assertNotNull(o);
}
}
12. Using Testcontainers for Integration Tests
Example: Testcontainers with dynamic properties
@SpringBootTest
@Testcontainers
class PostgresIT {
@Container static PostgreSQLContainer<?> pg = new PostgreSQLContainer<>("postgres:16");
@DynamicPropertySource
static void props(DynamicPropertyRegistry r) {
r.add("spring.datasource.url", pg::getJdbcUrl);
r.add("spring.datasource.username", pg::getUsername);
r.add("spring.datasource.password", pg::getPassword);
}
}
// Or @ServiceConnection (Boot 3.1+)
13. Testing Async Methods and Events
| Tool | Use |
|---|---|
| Awaitility | Poll for async condition |
@RecordApplicationEvents |
Capture published events |
CountDownLatch |
Synchronize listener completion |
| Sync executor in tests | SyncTaskExecutor bean override |