JUnit을 간단하게나마 이해하고 나서, 최근 시작한 스프링(Spring Regacy) 환경에서 개발을 하다가 Junit을 적용해보고 싶어서 사용하기 시작했습니다. 그러나 간단한 Junit 문제없이 실행이 되지만 스프링의 어노테이션을 적용한 DAO는 직접 테스트할 수 없었습니다. 원인을 찾아보니 Junit에서 스프링 설정 환경 로딩 문제와 관련 라이브러리 설정이 문제였습니다.
아래에서 차례로 문제와 해결방법을 살펴보겠습니다.
1. 스프링 환경 파일 설정하기
1.1 spring-test-*.jar
스프링 환경에서 JUnit을 실행하려면 spring-test-*.jar 가 필요합니다.
이를 위해서 Maven에서 가져올 수 있도록 pom.xml 파일의 Depedencis 영역에 아래 구문을 추가해 줍니다.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
<scope>test</scope>
</dependency>
현재 사용 중인 스프링 프레임워크의 버전을 통일하기 위해서는 <version> 태그의 값을 properties에 설정되어 있는 값을 가져올 수 있도록 ${org.springframework-version}로 설정하여야 합니다.
2. JUnit5에서 테스트 방법
2.1 JUnit5 Test Case 생성
JUnit Test 관련 파일들은 src/test/java 폴더를 기준으로 생성합니다.
해당 경로에서 마우스 오른쪽 버튼을 클릭해 'JUnit Test Case'를 선택합니다. 만약 없다면 Wizard에서 JUnit을 입력하고 검색된 항목에서 'JUnit Test Case'를 선택합니다.
제일 상단에 어떤 버전의 JUnit을 사용할지 선택할 수 있습니다.
JUnit 5는 'JUnit Jupiter test'라고 표시됩니다.
그다음 본인이 원하는 패키지명을 적고, 테스트 이름을 적습니다.
보통은 클래스 경로와 동일한 패키지로 구성하고, 클래스명+'Test'를 사용하는 경우가 많습니다.
저는 아직은 마음에 안 드는데 좋은 네이밍 방법은 좀 더 고민해봐야겠습니다.
기본 뼈대는 위와 같습니다.
2.2 별도의 applicationContext.xml 파일 관리
테스트 환경의 경우 여러 방법으로 구성이 가능합니다만 단위 테스트의 경우 가벼운 DB를 설치하여 로컬에서 테스트하고 실제 테스트 환경에 배포할 경우는 DB가 다르게 구성이 됩니다. 이럴 경우 applicationContext 파일을 text용으로 관리하면 조금 더 편리하게 테스트 환경을 구축할 수 있습니다.
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<import resource="applicationContext.xml"/>
</beans>
저는 간단하게 'src/test/resources' 경로에 applicationContextTest.xml 파일을 생성하고 기존의 applicationContext.xml 파일을 포함시켰습니다.
<import resource="applicationContext.xml"/>
현재는 제 로컬 DB에서 테스트도 함께 하고 있어서 따로 추가하지 않았지만, 만약 로컬 DB와 다른 별도의 테스트 DB가 구축되어 있다면 테스트는 로컬 DB로 설정해서 사용하고, 통합 테스트는 테스트 DB로 설정할 수 있습니다.
한 가지 주의할 점은 import 하는 xml의 namespace와 동일하게 설정이 되어 있어야 오류가 발생하지 않습니다.
2.3 Spring 설정 파일 로드하기
스프링의 어노테이션 정보를 로드하기 위해서는 applicationContext.xml 파일을 읽어 들여야 합니다. JUnit에서는 @ContextConfiguration을 사용하여 파일을 지정할 수 있습니다.
import 파일을 보면 'springframework.test...'를 포함하고 있으며 이것은 위에 설정한 spring-test-*.jar에 들어있습니다.
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(locations = "classpath:applicationContextTest.xml")
경로명 앞의 classpath는 resource 파일이 있는 곳을 지정합니다. 'src/main/resources', 'src/test/resources'를 기본으로 찾고 있으며 필요하다면 추가로 경로를 적어주거나 해당 폴더 이하의 폴더를 모두 탐색하도록 설정할 수 있습니다.
> config 경로 아래 있을 경우
@ContextConfiguration(locations = "classpath:config/applicationContextTest.xml")
> classpath 하위 경로를 탐색하는 방법
// classpath 모든 하위 경로 탐색
@ContextConfiguration(locations = "classpath:/**/applicationContextTest.xml")
// classpath 바로 아래 경로만 탐색
@ContextConfiguration(locations = "classpath:/*/applicationContextTest.xml")
2.4 JUnit5 : ExtendWith 설정
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "classpath:applicationContextTest.xml")
스프링 환경에서 JUunit을 테스트하려면 별도의 확장이 필요합니다.
JUnit5에서는 @ExtendWith를 사용해서 확장할 수 있으며 이때 필요한 클래스는 SpringExtension.class입니다.
2.5 JUnit5 Test Code 작성
스프링의 어노테이션을 사용해 DAO를 바인딩 변수를 선언하고 사용했습니다.
실제 실행결과는 2이지만 3으로 테스트 값을 설정해 오류를 발생시켜봤습니다.
원래 값인 2로 설정하면 Test를 무사히 통과하는 것을 확인할 수 있었습니다.
@ExpendWith 구문 설정이 되지 않은 경우
확장이 Load 되지 않으면 DAO 객체가 바인딩이 되지 않아서 NULL로 나옵니다.
저는 이 문제와 classpath 설정 때문에 한 시간 정도 구글링을 했었네요
3. JUnit4에서 테스트 방법
3.1 JUnit4 Test Case 생성
JUnit Test Case 생성 시 'JUnit 4 test'를 선택합니다.
3.2 Maven Dependency 수정
@RunWith에서 사용하는 SpringJUnit4ClassRunner.class, SpringRunner.class는 Junit 4.12 이상을 필요로 합니다.
처음 글을 작성할 때는 Junit 5로 먼저 테스트 하고 확인해서 Junit 5 라이브러리가 등록되어 있어서 문제가 없었습니다. 추후 확인해보니 처음 등록한 Spring Legacy Project에서 pom.xml의 junit 기본 버전이 4.7로 되어 있습니다. 이 부분을 최소 4.12 이상으로 수정해주면 됩니다.
3.3 스프링 설정 파일 로딩
스프링 설정 파일 로딩은 2.2절과 2.3절의 JUnit5에서 사용한 방법과 동일합니다.
@ContextConfiguration에 사용하는 것은 spring-test-*.jar에서 제공하는 것이어서 import 하는 파일은 동일합니다만, JUnit에서 사용하는 것들은 달라집니다.
JUnit4의 경우 하나의 파일에서 모든 것을 제공하기 때문에 'org.junit.Assert.*'와 'org.junit.Test'가 사용됩니다.
3.4 JUnit4 : @RunWith
JUnit5에서는 @RunWith를 사용해서 확장할 수 있으며 이때 필요한 클래스는 SpringJUnit4ClassRunner.class 입니다.
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContextTest.xml")
// 아래도 사용 가능
@RunWith(SpringRunner.class)
3.4 JUnit4 Test Code 작성
JUnit5에서와 마찬가지로 동일하게 스프링 어노테이션을 사용해서 JUnit 테스트를 사용할 수 있습니다.
2.5절의 예와 마찬가지로 일부러 오류를 발생시켜 보고 수정 후 테스트하였습니다.
3. 검토해볼 사항
3.1 JUnit4, JUnit5 라이브러리 혼용
위 설정은 JUnit4 관련 클래스를 로딩하여 테스트 코드를 작성하고 수행하였습니다.
그러나 실제 테스트 함수는 JUnit5를 사용한 것입니다.
import 파일을 살펴보면 org.junit.jupiter.*를 사용하고 있습니다. JUnit5에서 사용하는 라이브러리입니다.
실행은 문제가 없습니다만 마음 한편이 편하진 않습니다.
기존의 import를 삭제하고 나서 이클립스의 기능을 사용하면 JUnit5, JUnit4 모두 사용 가능하기에 둘 중 하나를 선택할 수 있도록 나옵니다.
첫 번째 제안의 'Assert.assertNotNull'은 JUnit4 라이브러리입니다. 두 번째의 'Assertions.assertNotNull'은 JUnit5의 라이브러리입니다.
지금은 JUnit5에서 JUnit4의 함수들과 함께 사용해도 문제가 없지만, 나중을 생각하면 라이브러리 의존은 통일시켜두는 것이 좋을 것 같습니다.
3.2 Run Configurations 설정
마우스 오른쪽 버튼을 클릭해서 실행하는 경우 Run Configurations 설정을 변경할 수 있습니다.
Run Configuration에서 왼쪽의 JUnit을 살펴보면 지금 작성한 JUnit 관련 파일들이 조회가 됩니다.
각 파일을 클릭하면 실행 환경을 설정할 수 있습니다.
Test 탭에서 Test runner 부분에서 JUnit 버전을 선택할 수 있습니다. 하위 호환이 지원되어서인지 JUnit5의 경우 JUnit4과 혼용하여도 문제없이 실행이 됩니다만 달라진 부분인 @ExpendWith와 같은 JUnit5 신규 태그가 있으면 Test runner 설정이 JUnit4인 경우 실행이 되지 않습니다.
'DevOps > Spring' 카테고리의 다른 글
[Spring] AOP의 ProceedingJoinPoint가 import가 안되는 경우 (0) | 2022.06.14 |
---|---|
[Spring] @Resource 어노테이션이 import가 안될 경우 (0) | 2022.06.12 |
[Spring] log4j.xml 오류 : Cannot find DTD (0) | 2022.06.10 |
[Spring] web.xml 오류 : Invalid element name: - description (0) | 2022.06.08 |
댓글