ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring Boot] Kotlin으로 REST API 만들기(5) - Mapper 구현 및 단위 테스트(Junit5)
    Spring Boot/Kotlin으로 REST API 만들기 2022. 10. 30. 10:45
    반응형

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

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

    1. TodoMapper.kt

    package com.example.springbootrestapi.mapper
    
    import com.example.springbootrestapi.domain.TodoRequest
    import com.example.springbootrestapi.domain.TodoResponse
    import org.springframework.stereotype.Repository
    
    @Repository
    interface TodoMapper {
    
      /** To-Do 목록 조회 */
      fun getTodos(todoRequest: TodoRequest): MutableList<TodoResponse>
    
      /** To-Do 상세 조회 */
      fun getTodoById(id: Long): TodoResponse
    
      /** To-Do 저장 */
      fun insertTodo(todoRequest: TodoRequest): Int
    
      /** To-Do 수정 */
      fun updateTodo(todoRequest: TodoRequest): Int
    
      /** To-Do 삭제 */
      fun deleteTodoById(id: Long): Int
    }

     

    2. todo.xml

    <?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.TodoRequest"
        resultType="com.example.springbootrestapi.domain.TodoResponse">
    
        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="long"
        resultType="com.example.springbootrestapi.domain.TodoResponse">
    
        SELECT *
          FROM TODO
         WHERE ID = #{id}
    
      </select>
    
      <insert id="insertTodo"
        useGeneratedKeys="true"
        keyProperty="id"
        parameterType="com.example.springbootrestapi.domain.TodoRequest">
    
        INSERT
          INTO TODO
             (
                  TITLE
                , DESCRIPTION
                , COMPLETED
             )
        VALUES
             (
                  #{title}
                , #{description}
                , #{completed}
             )
    
      </insert>
    
      <update id="updateTodo"
        parameterType="com.example.springbootrestapi.domain.TodoRequest">
    
        UPDATE TODO
           SET TITLE = #{title}
             , DESCRIPTION = #{description}
             , COMPLETED = #{completed}
         WHERE ID = #{id}
    
      </update>
    
      <delete id="deleteTodoById"
        parameterType="long">
    
        DELETE
          FROM TODO
         WHERE ID = #{id}
    
      </delete>
    
    </mapper>

     

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

    package com.example.springbootrestapi.mapper
    
    import com.example.springbootrestapi.domain.TodoRequest
    import org.junit.jupiter.api.Assertions
    import org.junit.jupiter.api.Assertions.assertEquals
    import org.junit.jupiter.api.Assertions.assertTrue
    import org.junit.jupiter.api.DisplayName
    import org.junit.jupiter.api.Test
    import org.springframework.beans.factory.annotation.Autowired
    import org.springframework.boot.test.context.SpringBootTest
    import org.springframework.test.context.ActiveProfiles
    import org.springframework.transaction.annotation.Transactional
    
    @SpringBootTest
    @ActiveProfiles("local")
    class TodoMapperTest {
    
      @Autowired
      lateinit var todoMapper: TodoMapper
    
      @Transactional
      @DisplayName("getTodos_To-Do 목록 조회")
      @Test
      fun 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)
    
        var todoRequest = TodoRequest().apply {
          this.title = "Title Junit Test Insert"
          this.description = "Description Junit Test Insert"
          this.completed = true
        }
    
        // When
        var todos = todoMapper.getTodos(todoRequest)
    
        // Then
        assertTrue(!todos.isEmpty())
      }
    
      @Transactional
      @DisplayName("getTodoById_To-Do 상세 조회")
      @Test
      fun testGetTodoById() {
    
        // Given
        var insertId = insertTodo("Title Junit Test Insert 01", "Description Junit Test Insert 01", false)
    
        // When
        var todoResponse = todoMapper.getTodoById(insertId)
    
        // Then
        assertEquals(insertId, todoResponse.id)
      }
    
      @Transactional
      @DisplayName("insertTodo_To-Do 저장")
      @Test
      fun testInsertTodo() {
    
        // Given
        var todoRequest = TodoRequest().apply {
          this.title = "Title Junit Test Insert"
          this.description = "Description Junit Test Insert"
          this.completed = false
        }
    
        // When
        todoMapper.insertTodo(todoRequest)
    
        // Then
        todoRequest.id?.let {
          var todoResponse = todoMapper.getTodoById(it)
          Assertions.assertEquals(todoRequest.title, todoResponse.title)
          Assertions.assertEquals(todoRequest.description, todoResponse.description)
          Assertions.assertEquals(todoRequest.completed, todoResponse.completed)
        } ?: throw Exception()
      }
    
      @Transactional
      @DisplayName("updateTodo_To-Do 수정")
      @Test
      fun testUpdateTodo() {
    
        // Given
        val insertId = insertTodo("Title Junit Test Insert", "Description Junit Test Insert", false)
    
        val todoRequest = TodoRequest().apply {
          this.id = insertId
          this.title = "Title Junit Test Update"
          this.description = "Description Junit Test Update"
          this.completed = true
        }
    
        // When
        todoMapper.updateTodo(todoRequest)
    
        // Then
        todoRequest.id?.let {
          var todoResponse = todoMapper.getTodoById(it)
          Assertions.assertEquals(todoRequest.title, todoResponse.title)
          Assertions.assertEquals(todoRequest.description, todoResponse.description)
          Assertions.assertEquals(todoRequest.completed, todoResponse.completed)
        } ?: throw Exception()
      }
    
      @Transactional
      @DisplayName("deleteTodoById_To-Do 삭제")
      @Test
      fun testDeleteTodoById() {
    
        // Given
        val insertId = insertTodo("Title Junit Test Insert", "Description Junit Test Insert", false)
    
        // When
        todoMapper.deleteTodoById(insertId)
    
        // Then
        val todoResponse = todoMapper.getTodoById(insertId)
        Assertions.assertNull(todoResponse)
      }
    
      fun insertTodo(
        title: String,
        description: String,
        completed: Boolean
      ): Long {
    
        var todoRequest = TodoRequest().apply {
          this.title = title
          this.description = description
          this.completed = completed
        }
    
        todoMapper.insertTodo(todoRequest)
    
        return todoRequest.id ?: 0
      }
    }

     

    4. 단위 테스트 확인

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

     

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

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

    반응형

    댓글

Designed by Tistory.