在現代軟體開發中,測試是確保程式碼品質和降低錯誤率的重要環節。對於使用Spring Boot開發的應用程式,進行單元測試能夠提升信心,確保API和服務正常運行。本文將介紹如何使用Spring Boot進行單元測試,包括測試API和服務層的最佳實踐。
單元測試是對應用程式中最小可測試單元的獨立檢驗。其目的是檢查該單元的正確性,以確保其如預期工作。在Spring Boot中,單元測試主要用到Junit和Mockito等框架。
如果使用Maven,確保 pom.xml 中包含以下依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
如果使用Gradle,則在 build.gradle 中添加:
testImplementation 'org.springframework.boot:spring-boot-starter-test'
my-spring-boot-app
│
├── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ └── java
│ └── com
│ └── example
│ └── demo
│ ├── UserControllerTest.java
│ └── UserServiceTest.java
│
├── pom.xml
假設我們有一個簡單的用戶控制器 (UserController):
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userService.getUserById(id)
.map(user -> ResponseEntity.ok().body(user))
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.createUser(user);
return new ResponseEntity<>(savedUser, HttpStatus.CREATED);
}
}
在 UserControllerTest.java 中,我們將測試這個控制器的功能
public class UserControllerTest {
private MockMvc mockMvc;
@Mock
private UserService userService;
@InjectMocks
private UserController userController;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
}
@Test
public void testGetUserById() throws Exception {
User user = new User(1L, "John Doe", "john.doe@example.com");
when(userService.getUserById(1L)).thenReturn(Optional.of(user));
RequestBuilder request = get("/api/users/1")
.accept(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isOk())
.andReturn();
String expectedResponse = new ObjectMapper().writeValueAsString(user);
assertEquals(expectedResponse, result.getResponse().getContentAsString());
}
@Test
public void testCreateUser() throws Exception {
User user = new User(null, "Jane Doe", "jane.doe@example.com");
User savedUser = new User(1L, "Jane Doe", "jane.doe@example.com");
when(userService.createUser(any(User.class))).thenReturn(savedUser);
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(user)))
.andExpect(status().isCreated());
verify(userService, times(1)).createUser(any(User.class));
}
}
接下來,我們將測試用戶服務 (UserService)
假設UserService如下所示:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public Optional<User> getUserById(Long id) {
return userRepository.findById(id);
}
public User createUser(User user) {
return userRepository.save(user);
}
}
在 UserServiceTest.java 中,測試UserService的功能
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testGetUserById() {
User user = new User(1L, "John Doe", "john.doe@example.com");
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
Optional<User> foundUser = userService.getUserById(1L);
assertEquals("John Doe", foundUser.get().getName());
}
@Test
public void testCreateUser() {
User user = new User(null, "Jane Doe", "jane.doe@example.com");
User savedUser = new User(1L, "Jane Doe", "jane.doe@example.com");
when(userRepository.save(any(User.class))).thenReturn(savedUser);
User result = userService.createUser(user);
assertEquals("Jane Doe", result.getName());
}
}
單元測試是Spring Boot開發過程中的重要組成部分。使用Junit和Mockito來測試API和服務層的程式碼不僅能提高程式碼品質,還能在日後維護和擴展時提供信心。透過遵循上述最佳實踐,可以構建出可靠而穩定的Spring Boot應用程式