학생 관리 모듈 유닛 테스트

JavaBeginner
지금 연습하기

소개

이 프로젝트에서는 JUnit 5 와 Mockito 를 사용하여 학생 관리 모듈에 대한 유닛 테스트를 생성하는 방법을 배우게 됩니다. 이 프로젝트는 StudentServiceImpl 클래스에 대한 테스트 생성과 StudentController 클래스에 대한 테스트 생성, 두 가지 주요 작업으로 구성됩니다.

🎯 과제

이 프로젝트에서 다음을 배우게 됩니다:

  • JUnit 5 를 사용하여 StudentServiceImpl 클래스를 테스트하기 위한 ServiceTests.java 파일 생성 방법
  • JUnit 5 와 Mockito 를 사용하여 StudentController 클래스를 테스트하기 위한 ControllerTests.java 파일 생성 방법
  • Spring Boot 테스트 기능, 예를 들어 @SpringBootTest@MockBean을 사용하여 필요한 컴포넌트를 로드하고 테스트를 위한 목 (mock) 을 생성하는 방법
  • StudentServiceImpl 클래스의 queryStudents(), insertStudent(), 및 deleteStudent() 메서드의 기능을 검증하기 위한 테스트 케이스 작성 방법
  • StudentController 클래스의 getStudents(), getStudent(), 및 modifyStudent() 메서드의 기능을 검증하기 위한 테스트 케이스 작성 방법

🏆 성과

이 프로젝트를 완료하면 다음을 수행할 수 있습니다:

  • JUnit 5 와 Mockito 를 사용하여 Spring Boot 애플리케이션에 대한 유닛 테스트 설정
  • Spring Boot 테스트 기능을 사용하여 필요한 컴포넌트를 로드하고 테스트를 위한 목 (mock) 생성
  • 서비스 및 컨트롤러 계층 구현의 정확성을 보장하기 위한 효과적인 테스트 케이스 작성
  • 어설션 (assertion) 을 사용하여 테스트된 메서드의 예상 동작을 검증

ServiceTests.java 파일 생성

이 단계에서는 JUnit 5 를 사용하여 StudentServiceImpl 클래스를 테스트하기 위한 ServiceTests.java 파일을 생성하는 방법을 배우게 됩니다.

  1. IDE 를 열고 프로젝트의 /test/java/org/labex/springboottesting 디렉토리로 이동합니다.
  2. ServiceTests.java라는 새 Java 파일을 생성합니다.
  3. ServiceTests.java 파일에 다음 코드를 추가합니다:
package org.labex.springboottesting;

import org.junit.jupiter.api.Test;
import org.labex.springboottesting.service.StudentServiceImpl;
import org.labex.springboottesting.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

@SpringBootTest(classes = StudentServiceImpl.class)
class ServiceTests {

    @Autowired
    private StudentServiceImpl service;

    @Test
    void testQueryStudents() {
        // Testing the queryStudents() method of the service to ensure correct data retrieval.
        List<Student> result = service.queryStudents();

        // Asserting that the size of the returned list matches the expected size.
        assertEquals(3, result.size());
    }

    @Test
    void testInsertStudent() {
        // Creating a sample student object to insert.
        Student student = new Student("1", "test", 18, "male");

        // Testing the insertStudent() method of the service to ensure successful insertion.
        Boolean result = service.insertStudent(student);

        // Asserting that the insertion operation was successful.
        assertTrue(result);
    }

    @Test
    void testDeleteStudent() {
        // Testing the deleteStudent() method of the service to ensure successful deletion.
        Boolean result = service.deleteStudent("20191001");

        // Asserting that the deletion operation was successful.
        assertTrue(result);
    }
}

ServiceTests 클래스는 테스트 클래스에서 StudentServiceImpl 구현 클래스를 로드하기 위해 @SpringBootTest(classes = StudentServiceImpl.class)로 어노테이션 처리됩니다. 이 클래스는 세 가지 테스트 메서드를 포함합니다:

  1. testQueryStudents(): 반환된 학생 목록의 크기가 예상 크기와 일치하는지 확인하기 위해 IStudentService 인터페이스의 queryStudents() 메서드를 테스트합니다.
  2. testInsertStudent(): 학생 삽입 작업이 성공적인지 확인하기 위해 IStudentService 인터페이스의 insertStudent() 메서드를 테스트합니다.
  3. testDeleteStudent(): 학생 삭제 작업이 성공적인지 확인하기 위해 IStudentService 인터페이스의 deleteStudent() 메서드를 테스트합니다.

ControllerTests.java 파일 생성

이 단계에서는 Mockito 테스트 프레임워크를 사용하여 StudentController 클래스를 테스트하기 위한 ControllerTests.java 파일을 생성하는 방법을 배우게 됩니다.

  1. IDE 를 열고 프로젝트의 /test/java/org/labex/springboottesting 디렉토리로 이동합니다.
  2. ControllerTests.java라는 새 Java 파일을 생성합니다.
  3. ControllerTests.java 파일에 다음 코드를 추가합니다:
package org.labex.springboottesting;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.labex.springboottesting.dao.IStudentDAO;
import org.labex.springboottesting.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.ArrayList;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest // Loading the Spring Boot application context.
@EnableWebMvc // Enables Spring Web MVC features.
@AutoConfigureMockMvc // Configures the MockMvc instance.
class ControllerTests {

    @Autowired
    private MockMvc mockMvc; // Autowires the MockMvc instance for simulating HTTP requests.

    private ObjectMapper objectMapper; // ObjectMapper for JSON conversion.

    @MockBean // MockBean annotation to create a mock for IStudentDAO.
    private IStudentDAO studentDAO;

    @BeforeEach
    void setUp() {
        // Initializing ObjectMapper to convert objects to JSON and vice versa.
        this.objectMapper = new ObjectMapper();
    }

    @Test
    void testGetStudents() throws Exception {
        // Creating sample students.
        Student s1 = new Student("20191001", "John", 18, "Male");
        Student s2 = new Student("20191069", "Lily", 19, "Female");

        // Creating a list of students and adding sample students to it.
        ArrayList<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);

        // Mocking the behavior of studentDAO to return the list of students when findStudentAll() is called.
        when(studentDAO.findStudentAll()).thenReturn(list);

        // Performing a GET request to retrieve all students and validating the response.
        this.mockMvc.perform(get("/api/v2/students")
                        .accept("application/json; charset=UTF-8")) // Sets the accept header to specify the expected response type.
                .andDo(print()) // Prints request and response details.
                .andExpect(status().isOk()) // Verifies that the response status is OK (200).
                .andReturn(); // Returns the MvcResult object for further assertions.
    }

    @Test
    void testGetStudent() throws Exception {
        // Creating a sample student.
        Student s1 = new Student("20191001", "John", 18, "Male");

        // Mocking the behavior of studentDAO to return the sample student when findStudentById() is called with "20191001".
        when(studentDAO.findStudentById("20191001")).thenReturn(s1);

        // Performing a GET request to retrieve a specific student by ID and validating the response.
        this.mockMvc.perform(get("/api/v2/student/20191001")
                        .accept("application/json; charset=UTF-8"))
                .andDo(print())
                .andExpect(status().isOk())
                .andReturn();
    }

    @Test
    void testModifyStudent() throws Exception {
        // Creating a sample student.
        Student s1 = new Student("20191001", "John", 18, "Male");

        // Converting the sample student to JSON format.
        String content = objectMapper.writeValueAsString(s1);

        // Mocking the behavior of studentDAO to return true when updateStudent() is called with any student object.
        when(studentDAO.updateStudent(any())).thenReturn(true);

        // Performing a PUT request to modify a student and validating the response.
        this.mockMvc.perform(put("/api/v2/student")
                        .content(content)
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept("application/json; charset=UTF-8"))
                .andDo(print())
                .andExpect(status().isOk())
                .andReturn();
    }
}

ControllerTests 클래스는 Spring Boot 애플리케이션 컨텍스트를 로드하기 위해 @SpringBootTest로, Spring Web MVC 기능을 활성화하기 위해 @EnableWebMvc로, MockMvc 인스턴스를 구성하기 위해 @AutoConfigureMockMvc로 어노테이션 처리됩니다. 이 클래스는 세 가지 테스트 메서드를 포함합니다:

  1. testGetStudents(): IStudentDAO 인터페이스의 동작을 목 (mock) 하고 /api/v2/students 엔드포인트에 GET 요청을 수행하여 StudentController 클래스의 getStudents() 메서드를 테스트합니다.
  2. testGetStudent(): IStudentDAO 인터페이스의 동작을 목 (mock) 하고 /api/v2/student/20191001 엔드포인트에 GET 요청을 수행하여 StudentController 클래스의 getStudent() 메서드를 테스트합니다.
  3. testModifyStudent(): IStudentDAO 인터페이스의 동작을 목 (mock) 하고, 샘플 학생 객체를 JSON 으로 변환하고, /api/v2/student 엔드포인트에 PUT 요청을 수행하여 StudentController 클래스의 modifyStudent() 메서드를 테스트합니다.

테스트 실행

ServiceTests.javaControllerTests.java 파일을 생성했으므로, 이제 테스트를 실행하여 StudentServiceImplStudentController 클래스의 기능을 확인할 수 있습니다.

  1. 터미널 또는 명령 프롬프트를 열고 다음 명령을 사용하여 프로젝트 디렉토리로 이동합니다:
cd ~/project/springboottesting/
  1. ServiceTests 클래스를 실행하려면 다음 명령을 실행합니다:
mvn test -Dtest=ServiceTests

이렇게 하면 ServiceTests 클래스의 세 가지 테스트 메서드가 실행되고 결과가 표시됩니다.

  1. ControllerTests 클래스를 실행하려면 다음 명령을 실행합니다:
mvn test -Dtest=ControllerTests

이렇게 하면 ControllerTests 클래스의 세 가지 테스트 메서드가 실행되고 결과가 표시됩니다.

콘솔 출력에서 통과 또는 실패한 테스트를 포함한 테스트 결과를 확인할 수 있습니다.

요약

축하합니다! 이 프로젝트를 완료했습니다. LabEx 에서 더 많은 랩을 연습하여 기술을 향상시킬 수 있습니다.

✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습✨ 솔루션 확인 및 연습