ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] REST API 만들기(5) - Mapper 구현 및 단위 테스트(Junit5)
    Spring Boot/2.7.x - REST API 만들기 2022. 9. 25. 22:15
    반응형

    REST API 만들기(5) - Mapper 구현 및 단위 테스트

    To-Do 조회, 등록, 수정, 삭제를 위한 TodoMapper.java, todo.xml를 구현한 후 JUnit5을 사용하여 단위 테스트를 할 수 있도록 TestTodoMapper.java 작성하세요.

     

    1. TodoMapper.java

    To-Do 상세 조회, 저장, 수정, 삭제 메서드를 추가하세요.

    package com.example.springbootrestapi.mapper;
    
    import com.example.springbootrestapi.domain.Todo;
    import java.util.List;
    
    public interface TodoMapper {
    
      /**
       * To-Do 목록 조회
       */
      List<Todo.Response> getTodos(Todo.Request todoRequest);
    
      /**
       * To-Do 상세 조회
       */
      Todo.Response getTodoById(int id);
    
      /**
       * To-Do 저장
       */
      int insertTodo(Todo.Request todoRequest);
    
      /**
       * To-Do 수정
       */
      int updateTodo(Todo.Request todoRequest);
    
      /**
       * To-Do 삭제
       */
      int deleteTodoById(int id);
    }

     

    2. todo.xml

    To-Do 상세 조회, 저장, 수정, 삭제를 SQL문을 추가하세요.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.example.springbootrestapi.mapper.TodoMapper">
    
      <select id="getTodos"
        parameterType="com.example.springbootrestapi.domain.Todo$Request"
        resultType="com.example.springbootrestapi.domain.Todo$Response">
    
        SELECT ID
             , TITLE
             , DESCRIPTION
             , COMPLETED
          FROM TODO
        <where>
          <if test="title != null and title != ''">
           AND TITLE LIKE CONCAT('%', #{title}, '%')
         </if>
         <if test="description != null and description != ''">
           AND DESCRIPTION LIKE CONCAT('%', #{description}, '%')
         </if>
         <if test="completed != null">
           AND COMPLETED = #{completed}
         </if>
        </where>
    
      </select>
    
      <select id="getTodoById"
        parameterType="int"
        resultType="com.example.springbootrestapi.domain.Todo$Response">
    
        SELECT *
          FROM TODO
         WHERE ID = #{id}
    
      </select>
    
      <insert id="insertTodo"
        useGeneratedKeys="true"
        keyProperty="id"
        parameterType="com.example.springbootrestapi.domain.Todo$Request">
    
        INSERT
          INTO TODO
             (
                  TITLE
                , DESCRIPTION
                , COMPLETED
              )
        VALUES
             (
                  #{title}
                , #{description}
                , #{completed}
              )
    
      </insert>
    
      <update id="updateTodo"
        parameterType="com.example.springbootrestapi.domain.Todo$Request">
    
        UPDATE TODO
           SET TITLE = #{title}
             , DESCRIPTION = #{description}
             , COMPLETED = #{completed}
         WHERE ID = #{id}
    
      </update>
    
      <delete id="deleteTodoById"
        parameterType="int">
    
        DELETE
          FROM TODO
         WHERE ID = #{id}
    
      </delete>
    
    </mapper>

     

    3. TestTodoMapper.java

    To-Do 목록 및 상세 조회, 저장, 수정, 삭제를 테스트할 수 있도록 단위 테스트를 추가하세요.

    @SpringBootTest
    테스트에 필요한 의존성을 제공합니다.
    @ActiveProfiles
    테스트 시 활성화하려는 profile을 설정할 수 있습니다.
    @Test
    테스트 메서드로 인식하고, 독립적으로 실행할 수 있도록 합니다.
    @Transactional
    테스트 시 데이터베이스에 저장된 결과를 커밋하지 않고 롤백합니다.
    @DisplayName  
    테스트 클래스 및 메서드의 이름을 지정할 수 있습니다.

    package com.example.springbootrestapi.mapper;
    
    import com.example.springbootrestapi.domain.Todo;
    import java.util.List;
    import javax.annotation.Resource;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.ActiveProfiles;
    import org.springframework.transaction.annotation.Transactional;
    
    @SpringBootTest
    @ActiveProfiles("local")
    class TodoMapperTest {
    
      @Resource
      TodoMapper todoMapper;
    
      @Transactional
      @DisplayName("getTodos_To-Do 목록 조회")
      @Test
      void testGetTodos() {
    
        // Given
        insertTodo("Title Junit Test Insert 01", "Description Junit Test Insert 01", false);
        insertTodo("Title Junit Test Insert 02", "Description Junit Test Insert 02", true);
        insertTodo("Title Junit Test Insert 03", "Description Junit Test Insert 03", false);
        insertTodo("Title Junit Test Insert 04", "Description Junit Test Insert 04", true);
        insertTodo("Title Junit Test Insert 05", "Description Junit Test Insert 05", false);
        Todo.Request todoRequest = Todo.Request.builder()
            .title("Title Junit Test Insert")
            .description("Description Junit Test Insert")
            .completed(true)
            .build();
    
        // When
        List<Todo.Response> todoResponses = todoMapper.getTodos(todoRequest);
    
        // Then
        Assertions.assertTrue(!todoResponses.isEmpty());
      }
    
      @Transactional
      @DisplayName("getTodoById_To-Do 상세 조회")
      @Test
      void testGetTodoById() {
    
        // Given
        int insertId = insertTodo("Title Junit Test Insert", "Description Junit Test Insert", false);
    
        // When
        Todo.Response todoResponse = todoMapper.getTodoById(insertId);
    
        // Then
        Assertions.assertEquals(insertId, todoResponse.getId());
      }
    
      @Transactional
      @DisplayName("insertTodo_To-Do 저장")
      @Test
      void testInsertTodo() {
    
        // Given
        Todo.Request todoRequest = Todo.Request.builder()
            .title("Title Junit Test Insert")
            .description("Description Junit Test Insert")
            .completed(false)
            .build();
    
        // When
        todoMapper.insertTodo(todoRequest);
    
        // Then
        Todo.Response todoResponse = todoMapper.getTodoById(todoRequest.getId());
        Assertions.assertEquals(todoRequest.getTitle(), todoResponse.getTitle());
        Assertions.assertEquals(todoRequest.getDescription(), todoResponse.getDescription());
        Assertions.assertEquals(todoRequest.getCompleted(), todoResponse.getCompleted());
      }
    
      @Transactional
      @DisplayName("updateTodo_To-Do 수정")
      @Test
      void testUpdateTodo() {
    
        // Given
        int insertId = insertTodo("Title Junit Test Insert", "Description Junit Test Insert", false);
        Todo.Request todoRequest = Todo.Request.builder()
            .id(insertId)
            .title("Title Junit Test Update")
            .description("Description Junit Test Update")
            .completed(true)
            .build();
    
        // When
        todoMapper.updateTodo(todoRequest);
    
        // Then
        Todo.Response todoResponse = todoMapper.getTodoById(todoRequest.getId());
        Assertions.assertEquals(todoRequest.getTitle(), todoResponse.getTitle());
        Assertions.assertEquals(todoRequest.getDescription(), todoResponse.getDescription());
        Assertions.assertEquals(todoRequest.getCompleted(), todoResponse.getCompleted());
      }
    
      @Transactional
      @DisplayName("deleteTodoById_To-Do 삭제")
      @Test
      void testDeleteTodoById() {
    
        // Given
        int insertId = insertTodo("Title Junit Test Insert", "Description Junit Test Insert", false);
    
        // When
        todoMapper.deleteTodoById(insertId);
    
        // Then
        Todo.Response todoResponse = todoMapper.getTodoById(insertId);
        Assertions.assertNull(todoResponse);
      }
    
      /**
       * To-Do 저장
       */
      int insertTodo(
          String title,
          String description,
          Boolean completed) {
    
        Todo.Request todoRequest = Todo.Request.builder()
            .title(title)
            .description(description)
            .completed(completed)
            .build();
    
        todoMapper.insertTodo(todoRequest);
    
        return todoRequest.getId();
      }
    }

     

    4. 단위 테스트 확인

    좌측에 초록색 버튼(Run Test)을 클릭 또는 소스 코드에서 우클릭하여 Run을 클릭하여 단위 테스트가 정상적으로 동작하는지 확인하세요. (단축키 : Ctrl + Shift + F10)

     

    소스 코드는 Github Repository - https://github.com/tychejin1218/springboot-rest-api (branch : section05) 를 참조하세요.

     

    GitHub에서 프로젝트 복사하기(Get from Version Control) - https://tychejin.tistory.com/325

    JUnit5의 @DisplayName 사용 시 Test Results에 표시되지 않는 경우 - https://tychejin.tistory.com/332

     

    반응형

    댓글

Designed by Tistory.