[JUnit]JNDI 설정시 단위테스트
JNDI 설정시에 단위테스트하는 방법을 소개합니다.
WAS 영역에 DataSource를 설정하고 JNDI 방식을 이용하고 있다면 단위테스트 수행시 별도의 설정이 필요합니다.
JNDI는 WAS 영역에 설정된 DB Connection 객체에 접근하기 위해 사용되는 기술입니다. 때문에 단위테스트를 진행할 때는 서버를 구동시키지 않기 때문에 context 설정 파일을 읽어도 이를 찾지 못하는 현상이 발생합니다.
설정 방법에 들어가기 앞서, 테스트 타겟은 아래와 같습니다.
테스트 단위
- Controller : CafeController
- Method : getMenu()
CafeController.java
@RequestMapping(value = "/cmp/getMenu.ajax", method = { RequestMethod.POST })
public @ResponseBody Map<String, Object> getMenu(HttpSession session, @RequestBody String jsonString) throws Exception {
Map<String, Object> resultMap = new HashMap<String, Object>();
try {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<String, Object>();
map = mapper.readValue(jsonString, new TypeReference<Map<String, String>>(){});
List<Object> resultList = cmpService.getMenu(map);
resultMap.put("resultList", resultList);
} catch (Exception e) {
e.printStackTrace();
}
return resultMap;
}
CafeService.java
public List<Object> getMenu(Map<String, Object> map) throws Exception;
CafeServiceImpl.java
@Override
public List<Object> getMenu(Map<String, Object> map) throws Exception {
return cmpDao.getMenu(map);
}
CafeDAO.java
public List<Object> getMenu(Map<String, Object> map) throws Exception {
return selectList("cmp.getMenu", map);
}
CafeMapper.xml
<select id="getMenu" resultType="hashMap">
WITH CAFE AS (
SELECT '아메리카노' MENU, 3000 PRICE FROM DUAL UNION ALL
SELECT '카페라떼' MENU, 4000 PRICE FROM DUAL UNION ALL
SELECT '바닐라라떼' MENU, 4500 PRICE FROM DUAL UNION ALL
SELECT '자몽에이드' MENU, 6500 PRICE FROM DUAL UNION ALL
SELECT '레몬에이드' MENU, 6500 PRICE FROM DUAL
)
SELECT MENU, PRICE
FROM CAFE
WHERE MENU = #{menu}
</select>
pom.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
테스트하려는 메소드는 POST 방식으로 호출되고 @RequestBody로 json 문자열을 받고, 결과를 Map에 담아서 리턴하고 있습니다.(@ResponseBody로 JSON 객체 변환)
그럼, 테스트 코드를 작성해보겠습니다.
package com.test.cmp.web;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import java.nio.charset.Charset;
import javax.annotation.Resource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations={
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml",
"file:src/test/resources/spring/context-*.xml",
"file:src/test/resources/mybatis-config.xml"
})
public class CafeControllerTest {
protected static final Logger logger = LoggerFactory.getLogger(CafeControllerTest.class);
@Autowired
private CafeController cafeController;
private MockMvc mockMvc;
private MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
@Before
public void setUp() throws Exception {
this.mockMvc = MockMvcBuilders.standaloneSetup(cafeController).build();
}
@Test
public void getMenuTest() throws Exception {
MockHttpServletRequestBuilder r = MockMvcRequestBuilders.post("/cmp/getMenu.ajax");
r.contentType(contentType);
r.content("{\"menu\":\"아메리카노\"}");
MvcResult rs = null;
rs = mockMvc.perform(r)
.andDo(print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andReturn();
}
}
먼저 프로젝트 설정 파일들의 경로는 다음과 같습니다.
- src/main/resources/spring : datasource 설정 파일, mybatis 연동/설정 파일, 트랜잭션 관리 등 설정 파일 모음
- src/main/webapp/WEB-INF/spring/appServlet : spring 초기 설정 파일
datasource 설정 파일이 있는 폴더를 src/main/resources/spring이 아닌 src/test/resources/spring 경로로 추가합니다. 그리고 설정되어 있는 JNDI를 아래와 같이 변경합니다.(TEST용 DB 접속 정보를 따로 작성해주는 작업)
src/main/resources/spring/context-datasource.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/testDB</value>
</property>
</bean>
src/test/resources/spring/context-datasource.xml
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
<property name="url" value="URL INFO"/>
<property name="username" value="ID"/>
<property name="password" value="PW"/>
</bean>
이후 @ContextConfiguration을 사용해 context 파일들을 로딩해주면 정상적으로 DB 연결이 가능한 것을 확인할 수 있습니다.
참고자료