ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] Junit을 사용하여 단위테스트(Spring-Test사용)
    IT/개발 기록 2018. 11. 5. 17:38


    Junit을 사용하여 단위테스트(Spring-Test사용)



    Junit이란?

    Java에서 독립된 단위테스트를 지원해주는 프레임워크


    Spring-Test란?

    @RunWith/@ContextConfiguration 등의 어노테이션을 활용하여

    Spring Framework에서 조금 더 편하게 테스트를 지원할 수 있게 해준다




    환경구성



    *풀소스 : https://github.com/devJJo/Junit-Spring


    1. Junit 라이브러리 추가


    1-1. Add Library선택



    1.2 JUnit선택 후 next




    2. pom.xml 필요한 라이브러리 추가


    - spring-test추가


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>SpringJunitTest</groupId>
        <artifactId>SpringJunitTest</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
        <build>
            <sourceDirectory>src</sourceDirectory>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.1</version>
                    <configuration>
                        <warSourceDirectory>WebContent</warSourceDirectory>
                    </configuration>
                </plugin>
            </plugins>
        </build>
     
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.20.RELEASE</version>
            </dependency>
     
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>4.3.20.RELEASE</version>
            </dependency>
        </dependencies>
    </project>
    cs



    3. spring을 활용함으로 xml설정파일 셋팅


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
            
        <!-- properties file 정보 -->    
        <context:property-placeholder 
            location="classpath:properties/values.properties"  />
            
        <!-- @Component @Value @Autowired 어노테이션을 선언한 클래스들을 스캐닝을 하기 위한 설정     -->
        <context:component-scan base-package="devjjo.junit.dto" />
            
        <!-- StringPrinter 클래스를 bean으로 등록-->
        <bean id="stringPrinter" class="devjjo.junit.dto.before.StringPrinter" />
        
        <!-- ConsolPrinter 클래스를 bean으로 등록 -->
        <bean id="consolePrinter" class="devjjo.junit.dto.before.ConsolePrinter" />
        
        <!-- Hello 클래스를 bean으로 등록 첫번째방법 -->
        <bean id="helloPrinter" class="devjjo.junit.dto.before.Hello" >
            <!-- setter injection 설정 -->
            <property name="name" value ="조성훈"/>
            <property name="printer" ref ="stringPrinter"/>
        </bean>
        
        <!-- Hello 클래스를 bean으로 등록 두번째방법 -->
        <bean id="helloC" class="devjjo.junit.dto.before.Hello" >
            <!-- constructor injection 설정 -->
            <constructor-arg index="0" value="${name}"/>
            <constructor-arg index="1" ref="consolePrinter"/>
            <property name="names">
                <list>
                    <value>${value1}</value>
                    <value>${value2}</value>
                    <value>${value3}</value>
                </list>
            </property
     
        </bean>
        
    </beans>
     
     
    cs


    4. 테스트할 클래스 생성


    - Hello.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    package devjjo.junit.dto;
     
    import java.util.List;
     
    import javax.annotation.Resource;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
     
    //Component 어노테이션 사용하면 xml에서 bean설정 해준느것과 같다 (EX:<bean id="stringPrinter" class =""> -> @Component)
    @Component
    public class Hello {
        
        // bean의 테스트 할 Value값 주는방식
        // 1. xml설정파일에 <property name="name" value ="조성훈"/> 과 같은 프로퍼티 설정 (이때, name맞춰줌)
        // 2. @Value("")로 어노테이션활용
        // 3. @Resource(name = "${sName}")로 properties설정파일 활용
        String name;
        
        // value의 값이 아니라 object를 넣어주는 방식
        // 1. @Autowired
        //      @Qualifier("stringPrinter") 해주면 partner빈 주입해주는것과 같다    
        // 2. @Resource(name = "${printer}") 활용
        Printer printer;
     
        public Hello() {
            System.out.println("Hello 기본 생성자 호출");
        }
     
        public Hello(String name, Printer printer) {
                System.out.println("Hello 오버로딩된 생성자");
            this.name = name;
            this.printer = printer;
        }
     
        public void setName(String name) {
            System.out.println("setNames 기본 생성자 호출 : " + name);
            this.name = name;
        }
     
        public void setPrinter(Printer printer) {
            System.out.println("setPrinter 기본 생성자 호출 : " + printer.getClass().getName());
            this.printer = printer;
        }
     
        public String sayHello() {
            return "Hello " + name;
        }
     
        public void print() {
            this.printer.print(sayHello());
        }
     
    }
     
    cs





    - Printer.java

    1
    2
    3
    4
    5
    6
    package devjjo.junit.dto;
     
    public interface Printer {
        public void print(String message);
    }
     
    cs




    - ConsolePrinter.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package devjjo.junit.dto;
     
    import org.springframework.stereotype.Component;
     
    @Component("conPrinter")
    public class ConsolePrinter implements Printer {
        public void print(String message) {
            System.out.println(message);
        }
    }
     

    cs



    - StringPrinter.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package devjjo.junit.dto;
     
    import org.springframework.stereotype.Component;
     
    @Component("conPrinter")
    public class ConsolePrinter implements Printer {
        public void print(String message) {
            System.out.println(message);
        }
    }
     
    cs



    - BeanSpringTest.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    package devjjo.junit.test;
     
    import java.util.List;
     
    import org.junit.Assert;
    import org.junit.Ignore;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     
    import devjjo.junit.dto.Hello;
    import devjjo.junit.dto.Printer;
     
     
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations="classpath:config/springbeans.xml")
    public class BeanSpringTest {
        
        
        @Autowired
        @Qualifier("helloPrinter")
        Hello hello;
     
    /*    @Autowired
        @Qualifier("helloC")
        Hello hello2;*/
        
        @Autowired
        @Qualifier("stringPrinter")
        Printer printer;
     
        @Test
        public void helloBean() {
            //값 비교 (Junit)
            Assert.assertEquals("Hello 조성훈", hello.sayHello());
     
            hello.print();
            Assert.assertEquals("Hello 조성훈", printer.toString());
        }
        
     
    }
     
    cs




    목표



    1.  BeanSpringTest.java를 Junit으로 실행하여 에러없이 초록불이 들어오면 된다. 초록불이 들어온다는건,  xml설정파일에서 주입한 값이 

    Assert.assertEquals("Hello 조성훈", hello.sayHello());

    이 부분에서 "Hello 조성훈"과 같다는 것이다.

    Assert는 org.junit.Assert을 import하여 사용할 수 있는 함수로 값을 비교해준다





    생각해 볼 부분



    1. Junit Spring-test를 사용하는 이유?

    controll, service, dao 단을 다 연결하고 main()함수에서 테스트를 진행할 때 

    에러가 난다면 어디서부터 잘못 됐는지 확인해야될 부분이 많다, 화면에서 값이 잘못 넘어왔는지

    서비스단 로직에서 잘못됐는지.. 또 여러명이 작업을 하고 합치는 경우에 자신이 만든 서비스 로직에 문제가 있는지

    단위테스트를 하고자 할 때 Junit을 활용한다


    2. Bean을 주입할 때 XML설정을 활용하는 방법과 소스에 Annotation을 활용하는 방법?

    XML설정 파일을 활용하는 방법과 소스상에 Annotation을 달아 확인하는 방법 중 

    진행하고있는 프로젝트에 맞게 적절히..활용해야 한다

    예를 들어, 개발중에는 개발자 들 각각 Annotation방법을 사용하지만

    실제 운영중에는 설정파일이 하나로 운영될 가능성이 높기 때문에 XML설정방법을 활용한다


    3. XML이나 소스상 변하는값을 넣어줄 땐 properties파일을 활용하면 소스변경없이 (재컴파일 없이) 

    사용할 수 있기 때문에 유연하다


    4. 빈주입을 할 때 앞에 두글자는 소문자로 해야 자동으로 xml설정파일에서 인식한다


    5. 사실.... 이런 단위테스트를 적용할 수 있는 환경이 아니라면 일을 위한 일을 하지 않는것이 좋을 것 같다.







    댓글