legacy code에 JUnit 4 환경 설정

gentledot·2021년 3월 28일
1

테스트와 로깅

목록 보기
1/5

참고자료

개요

  • 지금의 업무 환경에 단위 테스트 환경이 갖춰지지 않아 정보를 찾으면서 테스트 환경을 구현했던 경험을 정리하였습니다.
  • Spring Boot 나 JUnit 5가 아닌 경우에 환경설정 하는 방법이나 테스트를 작성하는 방법 등에 대해 우선적으로 동작했던 내용을 위주로 정리하였습니다.

잘못된 내용이나 더 나은 방식 등에 대한 의견은 댓글로 피드백 부탁드리겠습니다. :)

JUnit 설정

구현 환경

  • 구현 환경은 다음과 같습니다.
    • eGovFramework 3.5
    • Spring 4.0.9
  • 이 환경에서 가능하다면 JUnit 5를 적용해보려 하였지만 찾아본 바로는 Spring 4.3.0+ 부터 적용이 가능한 것으로 확인하였습니다.
  • 현재 환경이 spring version을 바로 올릴 수 있는 상황도 아니기 때문에 JUnit 4 환경을 구현하였습니다.

테스트 의존성 설정

  • pom.xml 내 테스트 환경을 구현하기 위한 dependency를 다음과 같이 추가하였습니다.
    <!-- test 환경 구성 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.0.9.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-inline</artifactId>
        <version>3.5.9</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.jayway.jsonpath</groupId>
        <artifactId>json-path</artifactId>
            <version>0.9.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.bgee.log4jdbc-log4j2</groupId>
        <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
        <version>1.16</version>
        <scope>test</scope>
    </dependency>
    • spring-test (4.0.9)
    • spring version과 동일하게 설정하였습니다.
      • test context 설정 관련
    • junit (4.13)
      • 테스트 환경 구축
    • mockito-inline(3.5.9)
      • mock 객체 활용 관련
      • inline을 사용하면 static (final) method에 대해 stubbing이 가능합니다.
    • json-path (0.9.0)
      • Spring MVC test 중 jsonPath 확인 용도
      • 해당 라이브러리를 쓰지 않으면 jsonPath에 대한 테스트를 작성할 수 없습니다.
      • MockMvcResultMatchers.jsonPath 확인 시 아래의 예외 발생
        java.lang.NoClassDefFoundError: com/jayway/jsonpath/InvalidPathException
        • 0.9.x 이상의 버전은 정상적으로 동작하지 않았습니다.
        // 2.4.0 버전으로 동작시 예외 발생
        java.lang.NoSuchMethodError: com.jayway.jsonpath.JsonPath.compile(Ljava/lang/String;[Lcom/jayway/jsonpath/Filter;)Lcom/jayway/jsonpath/JsonPath;
    • log4jdbc-log4j2-jdbc4.1 (1.16)
      • 테스트 실행 시 DB 트랜잭션의 로그 확인 용도
      • 테스트 환경 구현을 위한 필수 라이브러리는 아닙니다.
      • 기존 환경에서 log4sql을 사용하고 있으나 scope = test 인 경우에는 log가 출력되지 않는 문제가 있어 다음 라이브러리로 대체하였습니다.

추가 설정

  • servlet spec 변경
    • 기존 : 2.5 -> 변경 : 3.1.0
    • eGov 3.5에서는 javax.servlet-api가 2.5로 설정되어 있습니다.
  • jUnit 테스트에서 Mock MVC를 사용할 때 MockHttpSession 객체를 생성하게 되는데 이 때 서블릿 버전 3.1 이하에서는 SessionCookieConfig 클래스를 찾지 못하는 오류가 발생하기 때문에 변경이 필요합니다.
    java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig

.xml schemas

  • 아래 링크의 web-app xxx 관련 파일을 확인하면 schema(DTD) 에 대한 자세한 내용을 확인할 수 있습니다.

  • web-app 2.5

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	id="servlet-2_5"
    	version="2.5">
    </web-app>
  • web-app 3.0

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    	version="3.0">
    </web-app>
  • web-app 3.1

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    	version="3.1">
    </web-app>
  • web-app 4.0

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app
    	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    	version="4.0">
    </web-app>

servlet spec 변경 작업

  1. pom.xml 에서 javax.servlet-api 버전을 3.1.0으로 변경합니다.
    • 기존
      <!--        <dependency>-->
      <!--            <groupId>javax.servlet</groupId>-->
      <!--            <artifactId>servlet-api</artifactId>-->
      <!--            <scope>provided</scope>-->
      <!--            <version>2.5</version>-->
      <!--        </dependency>-->
    • 변경
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
      </dependency>
  2. web.xml > schema(DTD) 의 버전을 3.1로 변경
    • 기존
      <!--<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns="http://java.sun.com/xml/ns/javaee" 
      xmlns:web="http://java.sun.com/xml/ns/javaee" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">-->
    • 변경
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
      version="3.1">
  3. eclipse 프로젝트의 설정 내 facet 수정
    • 기존
      <!--<installed facet="jst.web" version="2.5"/>-->
    • 변경
      <installed facet="jst.web" version="3.1"/>

Log4jdbc2 설정

  • scope = test 일 때 실행 시 DB Transaction 관련 로그를 확인할 수 있도록 의존성을 추가하였습니다.

  • test 환경에서 log 출력을 위해 다음과 같이 파일을 구성하였습니다.
    test 내 logging 구성

  • log4j2.properties 파일에는 아래의 설정을 입력하였습니다.

    // 필수 입력
    log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
    // sql = mySQL
    log4jdbc.drivers=com.mysql.jdbc.Driver
    // 잘리는 log가 없도록 제한 해제 (0)
    log4jdbc.dump.sql.maxlinelength=0
  • 해당 logger가 transaction을 읽어들이기 위해서는 dataSource의 driverclass와 url를 수정하여야 한다.

    // 기존 설정
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<property name="driverClassName" value="core.log.jdbc.driver.MysqlDriver"/>
    	<property name="url" value="jdbc:mysql://--" />
    	...
    </bean>
    // 수정 후
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
        <property name="url" value="jdbc:log4jdbc:mysql://--"
    </bean>
  • log4j2-test.xml 를 생성하여 test 실행 시 log 출력을 설정하였습니다.

    • log4jdbc2에서는 sqlonly, sqltiming, audit, resultset, resultsettable, connection 출력을 지원합니다.

      <!-- log SQL with timing information, post execution -->
      <logger name="log4jdbc.log4j2" level="WARN" additivity="false">
          <appender-ref ref="console"/>
      </logger>
      
      <logger name="jdbc.sqlonly" level="INFO" additivity="false">
          <AppenderRef ref="console" />
      </logger>
      <logger name="jdbc.sqltiming" level="DEBUG" additivity="false">
          <AppenderRef ref="console" />
      </logger>
      <logger name="jdbc.audit" level="OFF" additivity="false">
          <AppenderRef ref="console" />
      </logger>
      <logger name="jdbc.resultset" level="OFF" additivity="false">
          <AppenderRef ref="console" />
      </logger>
      <logger name="jdbc.resultsettable" level="INFO" additivity="false">
          <AppenderRef ref="console" />
      </logger>
      <logger name="jdbc.connection" level="OFF" additivity="false">
          <AppenderRef ref="console" />
      </logger>
    • 자세한 설정 방법은 다음 링크에서 확인할 수 있습니다. https://log4jdbc.brunorozendo.com/

profile
그동안 마신 커피와 개발 지식, 경험을 기록하는 공간

0개의 댓글