Study/Spring Boot

Spring Boot (1) MybatisTest를 통한 Mapper 단위 테스트

개발 환경 : JAVA 1.8 / Spring Boot 2.4.1 / Gradle 6.7.1 / MySql

IDE : IntelliJ 20.3.3

Dependency : mybatis-spring-boot-starter-test 2.1.3

 

* 해당 포스팅은 공식문서를 참조하여 작성했습니다.

mybatis Test 공식문서 링크

 

1. 필요한 의존 추가

1.1 Mybatis Test 추가

mybatis-test                                                                                                                                                  

// Gradle의 경우
dependencies {
    testCompile("org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.1.3")
}

// Maven의 경우
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter-test</artifactId>
    <version>2.1.3</version>
    <scope>test</scope>
</dependency>

 

1.2 필요한 설정 추가 ( application.yml )

application.yml

		# 생략 #

datasource:
    username: #####
    password: #####
    driver-class-name: com.mysql.cj.jdbc.Driver # mysql 이외 각각 사용하는 DB Driver 설정
    url: #####
    
    hikari: # 해당 설정은 jdbc connection 이외 다른 connectio Pool 사용 시 설정
            # 여기선 hikariCP를 사용
            # hikariCP 설정내용은 생략
            

mybatis:

    # mapper.xml 파일이 위치할 패키지 경로를 입력
    mapper-location: classpath:/mapper/**/*.xml 
    
    # 커스텀 config 사용 시 입력
    config-location: classpath:/mybatis-config.xml
    
		# 생략 # 


 

2. 테스트 할 Mapper Interface, Mapper.xml 작성

OrderMapper.java

package com.mapper;


import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

// @Mapper 어노테이션을 통한 mapper 등록
@Mapper
public interface OrderMapper {

	// @Select, @insert 등의 어노테이션으로 xml 작성 없이 간단한 쿼리문을 날릴 수 있음.
	// @Select("Select * from orderbook where seq = #{seq}")
	OrderVO getOrder(@Param("seq") String seq);


}

 

OrderMapper.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.xxx.OrderMapper">

    <select id="getTest" resultType="OrderVO">
        Select *
        from orderbook
        where seq = #{seq}
    </select>


</mapper>

 

3. 테스트 클래스 작성 및 테스트

3.1 테스트 클래스 작성

 

OrderTest.java

package com.xxx.orders

import com.xxx.OrderMapper;
import com.xxx.OrderVO;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;

import static org.assertj.core.api.Assertions.assertThat;

// JUnit5 사용 시 작성, MybatisTest 2.0.1버전 이상에서 생략 가능
// @ExtendWith(SpringExtension.class)
// JUnit4 사용 시 작성
// @RunWith(SpringRunner.class)

// @MybatisTest 어노테이션 추가
@MybatisTest

// 실 데이터베이스에 연결 시 필요한 어노테이션
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class OrderTest {

    @Autowired
    private OrderMapper orderMapper;

    @Test
    @DisplayName("Order Mapper Test")
    public void mybatis_Mapper_XML_테스트() throws Exception {

        // given
        String seq = "1";

        // when
        OrderVO vo = orderMapper.getOrder(seq);

        // then
        assertThat(vo.getSeq).isEqualTo("1");

    }


}

3.2 테스트 결과

 

 

4. 정리

mybatis를 사용할 경우 mapper별 단위 테스트를 하는 법을 알아보았다.

 

이번 테스트가 이미 실제 서비스가 되고있는 어느정도 로직이 완성된 프로젝트에서의 테스트라는 점도 있었고,

확실히 이전에 전체 테스트만을 구현하여 스프링이 해당 서비스에 관련한 설정 전부를 실행하느라 기다리는 것보단 빨라졌지만

만약 프로젝트 초반부터 단위 테스트를 하며 서비스를 구현하게 될 경우엔 실 데이터베이스를 사용한 테스트가 아니라

인-메모리 데이터베이스(In-memory DB, ex. H2) 를 사용한 테스트를 구상해봐야겠다.

 

물론 실제 데이터베이스에서 값이 제대로 나오는지 보려면 이 테스트가 맞겠지만, 

실제 데이터베이스와의 통신을 전제로 하는 테스트라서 그런지

스프링부트 임베디드 설정들이 실행되는 것을 기다려야 한다는 단점이 있었기 때문이다.

둘 중에 각각 맞는 상황의 테스트를 사용하는 거겠지.

 

다음은 JUnit과 함깨 Spring Boot 테스트를 할 때 많이 사용되고 있는 Mockito를 통한

Service 단위 테스트를 공부하고 정리해보려 한다.

 

인-메모리 데이터베이스를 이용한 단위 테스트도 Service 테스트가 빨리 끝나서 시간이 남는다면 공부해봐야겠다.

 

* 참고자료

mybatis-test 공식문서 

[Junit] Test Code 작성시 DI(Dependencies Inject)를 적용하는 방법