Prerequisites
- JDK 17 or later
- Maven or Gradle
- IDE (IntelliJ IDEA, Eclipse, etc.)
Step 1: Set Up a Spring Boot Project
1.1 Create a New Spring Boot Project
Use Spring Initializr to create a new project with the following dependencies:
- Spring Web
- Spring Boot Test
Download and unzip the project, then open it in your IDE.
Step 2: Add Testing Dependencies
Ensure you have the necessary test dependencies in your pom.xml
(for Maven) or build.gradle
(for Gradle).
For Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
For Gradle:
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Step 3: Create a Simple Spring Boot Application
3.1 Create a Model Class
Create a simple model class to represent the data in your application.
package com.example.demo.model;
public class User {
private Long id;
private String name;
private String email;
// Getters and setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
3.2 Create a Service Class
Create a service class that performs business logic.
package com.example.demo.service;
import com.example.demo.model.User;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
private final List<User> users = new ArrayList<>();
public List<User> getAllUsers() {
return users;
}
public Optional<User> getUserById(Long id) {
return users.stream().filter(user -> user.getId().equals(id)).findFirst();
}
public User addUser(User user) {
users.add(user);
return user;
}
public void deleteUserById(Long id) {
users.removeIf(user -> user.getId().equals(id));
}
}
3.3 Create a REST Controller
Create a REST controller to handle HTTP requests.
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userService.getUserById(id);
return user.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<User> addUser(@RequestBody User user) {
User createdUser = userService.addUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUserById(@PathVariable Long id) {
userService.deleteUserById(id);
return ResponseEntity.noContent().build();
}
}
Step 4: Write Unit Tests
Unit tests focus on testing individual application components in isolation. We'll use JUnit 5 and Mockito for unit testing.
4.1 Test the Service Layer
Create a test class for the UserService
class.
package com.example.demo.service;
import com.example.demo.model.User;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
class UserServiceTest {
private UserService userService;
@BeforeEach
void setUp() {
userService = new UserService();
}
@Test
void getAllUsers_shouldReturnEmptyList() {
List<User> users = userService.getAllUsers();
assertThat(users).isEmpty();
}
@Test
void addUser_shouldAddUser() {
User user = new User();
user.setId(1L);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
userService.addUser(user);
List<User> users = userService.getAllUsers();
assertThat(users).hasSize(1);
assertThat(users.get(0)).isEqualTo(user);
}
@Test
void getUserById_shouldReturnUser() {
User user = new User();
user.setId(1L);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
userService.addUser(user);
Optional<User> retrievedUser = userService.getUserById(1L);
assertThat(retrievedUser).isPresent();
assertThat(retrievedUser.get()).isEqualTo(user);
}
@Test
void deleteUserById_shouldRemoveUser() {
User user = new User();
user.setId(1L);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
userService.addUser(user);
userService.deleteUserById(1L);
List<User> users = userService.getAllUsers();
assertThat(users).isEmpty();
}
}
Explanation:
@BeforeEach
: Initializes theUserService
before each test.@Test
: Marks a method as a test method.assertThat
: Provided by AssertJ, used for making assertions about the test results.
Step 5: Write Integration Tests
Integration tests verify that different parts of the application work together as expected.
5.1 Test the REST Controller
Create a test class for the UserController
class.
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import java.util.Collections;
import java.util.Optional;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
private User user;
@BeforeEach
void setUp() {
user = new User();
user.setId(1L);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
}
@Test
void getAllUsers_shouldReturnEmptyList() throws Exception {
Mockito.when(userService.getAllUsers()).thenReturn(Collections.emptyList());
mockMvc.perform(get("/users"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(0));
}
@Test
void addUser_shouldCreateUser() throws Exception {
Mockito.when(userService.addUser(Mockito.any(User.class))).thenReturn(user);
mockMvc.perform(post("/users")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\": \"John Doe\", \"email\": \"john.doe@example.com\"}"))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1L))
.andExpect(MockMvcResultMatchers.jsonPath("$.name").value("John Doe"))
.andExpect(MockMvcResultMatchers.jsonPath("$.email").value("john.doe@example.com"));
}
@Test
void getUserById_shouldReturnUser() throws Exception {
Mockito.when(userService.getUserById(1L)).thenReturn(Optional.of(user));
mockMvc.perform(get("/users
/1"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1L))
.andExpect(MockMvcResultMatchers.jsonPath("$.name").value("John Doe"))
.andExpect(MockMvcResultMatchers.jsonPath("$.email").value("john.doe@example.com"));
}
@Test
void deleteUserById_shouldReturnNoContent() throws Exception {
mockMvc.perform(delete("/users/1"))
.andExpect(MockMvcResultMatchers.status().isNoContent());
}
}
Explanation:
@WebMvcTest(UserController.class)
: Sets up a test context for theUserController
class and configures the necessary beans for testing web MVC controllers.@MockBean
: Creates a mock of theUserService
bean.MockMvc
: Provides a powerful way to perform and verify HTTP requests and responses.MockMvcResultMatchers
: Provides matchers for validating responses.
Step 6: Running the Tests
6.1 Run the Tests
You can run the tests using your IDE or from the command line using Maven or Gradle.
For Maven:
./mvnw test
For Gradle:
./gradlew test
6.2 Verify the Test Results
Ensure that all tests pass successfully. The unit tests should verify the correctness of the UserService
, and the integration tests should verify the REST API endpoints provided by the UserController
.
Conclusion
In this tutorial, you have learned how to set up and perform different types of tests in a Spring Boot 3.2 application. We covered:
- Setting up a Spring Boot project
- Creating a simple application with a model, service, and controller
- Writing unit tests using JUnit 5 and Mockito
- Writing integration tests for the REST controller using
@WebMvcTest
andMockMvc
Testing is a crucial part of developing reliable and maintainable software. By leveraging Spring Boot's powerful testing support, you can ensure your application behaves as expected and catch issues early in the development process.
Comments
Post a Comment