▸Spring MVC/개발 TIP

jUnit, Spring-Test 라이브러리 사용법

코데방 2020. 3. 19.
728x90

[ jUnit ]

  • 전체 프로젝트(특히 WAS)를 구동하지 않고 단위 코드 테스트를 할 수 있게 해주는 라이브러리

[ Spring-Test ]

  • jUnit을 확장한 스프링의 테스트 라이브러리

스프링 MVC 프로젝트를 진행할 때 코드 테스트를 할 때마다 WAS 구동을 하면 꽤나 답답한 경우가 많습니다. 이 때 jUnit 기능을 사용하면 프로젝트의 자원을 이용하면서도 필요한 코드만 간단하게 테스트해볼 수 있습니다. 다른 프로젝트를 하나 만들어서 테스트해볼 수도 있겠지만 이 경우 여러 가지 설정값이나 기능들을 사용할 수 없어 한계가 있습니다. 또

 

테스트를 하기 위한 코드는 "src/test/java" 와 "src/test/resources" 폴더 안에 넣고 사용하면 됩니다. 혹시 jUnit 라이브러리 import가 되지 않는다면 아래 링크를 참조하시면 됩니다.

 

[Spring MVC/- 개발 TIP] - Junit 라이브러리 import가 되지 않을 때

 

 


 

 

1. 메이븐 "pom.xml" jUnit, spring-test 라이브러리 의존 설정

 

최신버전 스프링에 jUnit은 자동으로 설정되어 있는 것 같습니다. 만약 "junit"을 검색했는데 없다면 아래 코드로 추가해주시면 됩니다. "spring-test"도 마찬가지입니다. 버전은 maven docs에서 보고 변경해도 무방합니다. 블로그 좌측 하단 Link 에서 접속할 있습니다.

 

		<!-- Test -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
        
        
		<!-- Spring Test -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

 

 


 

 

2. jUnit의 테스트 지원 어노테이션

 

@Test

테스트를 수행하는 메소드를 지정합니다. jUnit에서는 각각의 테스트가 서로 영향을 주지 않고 독립적으로 실행되는 것을 지향합니다. 따라서 @Test 단위 마다 필요한 객체를 생성해 지원해줍니다. 

 

@Ignore

테스트를 실행하지 않도록 해줍니다. 메소드는 남겨두되 테스트에 포함되지 않도록 하려면 이 어노테이션을 붙여두면 됩니다.

 

@Before / @After

테스트 메소드가 실행되기 전, 후로 항상 실행되는 메소드를 지정합니다. 공통적으로 실행되어야 하는 메소드가 있다면 어노테이션을 붙여주면 됩니다. 각각의 테스트 메소드에 적용됩니다.

 

@BeforeClass / @AfterClass

각각의 메소드가 아닌 해당 클래스에서 딱 한번만 수행되는 메소드입니다. 테스트 메소드의 갯수와 상관없이 딱 한번만 실행됩니다.

 

 

 

 


 

 

3. Spring-Test의 어노테이션

 

@RunWith(SpringJUnit4ClassRunner.class)

ApplicationContext를 만들고 관리하는 작업을 할 수 있도록 jUnit의 기능을 확장해줍니다. 스프링의 핵심 기능인 컨테이너 객체를 생성해 테스트에 사용할 수 있도록 해준다고 보면 됩니다. 원래 jUnit에서는 테스트 메소드별로 객체를 따로 생성해 관리하는 반면, Spring-Test 라이브러리로 확장된 jUnit에서는 컨테이너 기술을 써서 싱글톤으로 관리되는 객체를 사용해 모든 테스트에 사용하게 됩니다.

 

@ContextConfiguration(locations = "classpath:xml파일위치")

스프링 빈(Bean) 설정 파일의 위치를 지정할 수 있습니다. 굳이 별도로 컨테이너를 추가하지 않고 Bean을 등록해둔 xml 파일을 지정해 컨테이너에서 사용할 수 있도록 해줍니다. 위의 @RunWith 어노테이션은 컨테이너를 생성하겠다는 의미인데, 어떤 파일을 참조할지 모르는 상태이기 때문에 이 어노테이션을 함께 써줘야 합니다.

 

파일 위치의 루트는 "src/test/resources" 폴더입니다. 필요한 설정 파일은 이곳에 복사해놓고 사용해도 됩니다. 하지만 매번 파일을 복사하면 힘들기 때문에 "file:Full path" 형식으로 써주면 운영 개발에서 사용하는 파일을 불러올 수 있습니다. 대괄호 { } 를 붙이면 여러개도 모두 가져올 수 있습니다. 아래 예시에서 추가 설명하겠습니다.

 

@Autowired

스프링에서 사용하는 것과 같습니다. 자동으로 의존성 주입을 해줍니다. 

 

 


 

 

4. 테스트 클래스 작성

 

아래와 같은 코드로 어노테이션을 이용해 테스트 코드를 작성하면 됩니다. 필요한 Bean 객체를 모두 하나의 컨테이너에 넣고, getBean()을 사용해 꺼내 쓰면 됩니다. 그리고 실행할 때 무엇으로 실행할지 물어보면 jUnit을 선택해주면 됩니다. 

 

package com.hsweb.springweb;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

// spring-test 사용
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/root-context.xml")
public class Test {

	@Autowired
	private ApplicationContext ctx;
	
	@Before
	public void beforeClass() {
		System.out.println("-----테스트 시작-----");
	}
	
	@After
	public void afterClass() {
		System.out.println("-----테스트 종료-----");
	}

	@org.junit.Test
	public void dbTest() {

		// 컨테이너에서 getBean()
		SqlSessionTemplate session 
		= ctx.getBean("sqlSessoinTemplate",SqlSessionTemplate.class);
		System.out.println(session);
	}
}

 

 

 

하지만 위와 같이 ContextConfiguration의 location을 설정한다면 일일이 필요한 xml 설정 파일을 복사해서 붙여넣어줘야 합니다. 따라서 아래와 같이 파일 위치를 Full path로 주면 해당 위치에 있는 파일을 참조해 컨테이너를 생성합니다.

 

@ContextConfiguration
(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml",
		"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})

 

 

그런데 또 일일이 위와 같은 파일 위치를 테스트 클래스에 모두 붙여주면 계속 번거로워지기 때문에, 위의 정보를 가지고 있는 부모 클래스를 하나 생성해두고 상속받아 사용하면 좀 더 편하게 관리할 수 있습니다.

 

package hs.spring.hsweb;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

// 컨테이너 설정 정보를 가지고 있는 설정 클래스
// 이 클래스를 상속받으면 컨테이너 ctx 필드를 사용할 있게 됨
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml",
		"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
public class Configure {

	@Autowired
	public ApplicationContext ctx;
	
}
package hs.spring.hsweb;

import java.sql.Connection;
import javax.sql.DataSource;
import org.junit.Test;

// Configure 클래스를 상속받았으므로 따로 컨테이너 설정을 하지 않아도 됨
public class DBTest extends Configure {
	
	@Test
	public void dbConnect() throws Exception {
		
		DataSource dataSource = (DataSource) ctx.getBean("dataSource");
		Connection conn = (Connection) dataSource.getConnection();
		System.out.println("성공 : " + conn);
	}
}

 

728x90

댓글

💲 추천 글