Understand testing techniques for Spring applications, including unit testing of controllers and services, and integration testing of REST APIs. Learn to secure Spring Boot applications using Spring Security, implementing basic authentication, database-backed user authentication, and JWT-based authorization.
Overview:
Tools and Frameworks:
@SpringBootTest
, MockMvc
).Dependencies (for Spring Boot):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Purpose: Test controller logic in isolation, mocking dependencies (e.g., services).
Key Tools:
Example:
import com.example.controller.EmployeeController;
import com.example.model.Employee;
import com.example.service.EmployeeService;
import org.junit.jupiter.api.Test;
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.test.web.servlet.MockMvc;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(EmployeeController.class)
public class EmployeeControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private EmployeeService employeeService;
@Test
public void testGetEmployeeById() throws Exception {
Employee employee = new Employee(1, "John Doe", "Developer");
when(employeeService.getById(1)).thenReturn(employee);
mockMvc.perform(get("/api/employees/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(1))
.andExpect(jsonPath("$.name").value("John Doe"));
}
}
Purpose: Test business logic in services, mocking repositories or other dependencies.
Key Tools: Mockito for mocking dependencies, JUnit for assertions.
Example:
import com.example.model.Employee;
import com.example.repository.EmployeeRepository;
import com.example.service.EmployeeService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@SpringBootTest
public class EmployeeServiceTest {
@Autowired
private EmployeeService employeeService;
@MockBean
private EmployeeRepository employeeRepository;
@Test
public void testGetById() {
Employee employee = new Employee(1, "John Doe", "Developer");
when(employeeRepository.findById(1)).thenReturn(Optional.of(employee));
Employee result = employeeService.getById(1);
assertEquals("John Doe", result.getName());
}
}
Purpose: Test the entire application stack (controllers, services, repositories, database) to ensure components work together.
Key Tools:
Example:
import com.example.model.Employee;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class EmployeeApiIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetAllEmployees() {
ResponseEntity<Employee[]> response = restTemplate.getForEntity("/api/employees", Employee[].class);
assertEquals(200, response.getStatusCodeValue());
}
}