Spring Boot Testing: Unit Test และ Integration Test
#java13 เม.ย. 2569
Testing ใน Spring Boot
Spring Boot มี testing support ที่ดีมาก ด้วย @SpringBootTest, @WebMvcTest, @DataJpaTest และ Mockito
Unit Test กับ Mockito
import org.junit.jupiter.api.*;
import org.mockito.*;
import static org.mockito.Mockito.*;
import static org.assertj.core.api.Assertions.*;
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void findById_WhenUserExists_ReturnsUser() {
// Arrange
User user = new User(1L, "สมชาย", "somchai@example.com");
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
// Act
Optional<User> result = userService.findById(1L);
// Assert
assertThat(result).isPresent();
assertThat(result.get().getName()).isEqualTo("สมชาย");
verify(userRepository, times(1)).findById(1L);
}
@Test
void findById_WhenUserNotFound_ThrowsException() {
when(userRepository.findById(99L)).thenReturn(Optional.empty());
assertThatThrownBy(() -> userService.findById(99L))
.isInstanceOf(UserNotFoundException.class)
.hasMessageContaining("99");
}
}
Controller Test กับ MockMvc
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Autowired
private ObjectMapper objectMapper;
@Test
void getUser_WhenExists_Returns200() throws Exception {
User user = new User(1L, "สมชาย", "somchai@example.com");
when(userService.findById(1L)).thenReturn(Optional.of(user));
mockMvc.perform(get("/api/users/1")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("สมชาย"))
.andExpect(jsonPath("$.email").value("somchai@example.com"));
}
@Test
void createUser_WithValidData_Returns201() throws Exception {
CreateUserRequest request = new CreateUserRequest("สมชาย", "somchai@example.com");
User created = new User(1L, "สมชาย", "somchai@example.com");
when(userService.create(any())).thenReturn(created);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id").value(1));
}
}
Repository Test
@DataJpaTest
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void findByEmail_WhenExists_ReturnsUser() {
User user = new User("สมชาย", "somchai@example.com");
userRepository.save(user);
Optional<User> found = userRepository.findByEmail("somchai@example.com");
assertThat(found).isPresent();
assertThat(found.get().getName()).isEqualTo("สมชาย");
}
}
Integration Test
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureTestDatabase
class UserIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void createAndGetUser() {
CreateUserRequest request = new CreateUserRequest("สมชาย", "somchai@example.com");
ResponseEntity<User> created = restTemplate.postForEntity("/api/users", request, User.class);
assertThat(created.getStatusCode()).isEqualTo(HttpStatus.CREATED);
Long id = created.getBody().getId();
ResponseEntity<User> found = restTemplate.getForEntity("/api/users/" + id, User.class);
assertThat(found.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(found.getBody().getName()).isEqualTo("สมชาย");
}
}
สรุป
Spring Boot testing ครอบคลุมทุกระดับ ตั้งแต่ unit test ด้วย Mockito ไปจนถึง integration test ด้วย @SpringBootTest ควรเขียน test ทุกระดับเพื่อ confidence ที่สูงครับ