[Spring] Junit을 사용하여 단위테스트(Spring-Test사용)
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); } } |
- 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. 사실.... 이런 단위테스트를 적용할 수 있는 환경이 아니라면 일을 위한 일을 하지 않는것이 좋을 것 같다.