Framework/Spring

[JUnit]JNDI 설정시 단위테스트

SHXL2 2021. 8. 23. 21:59
반응형

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 연결이 가능한 것을 확인할 수 있습니다.

 

참고자료
 

[Spring Fw] 스프링프레임워크에서 JUnit 을 이용한 API 테스트 : Spring Framework + JUnit + JNDI

스프링프레임워크에서 JUnit 을 이용한 API 테스트 : Spring Framework + JUnit + JNDI junit 없이 매번 was 재기동 및 postman 호출로 api 결과들을 확인하는 방식으로 테스트를 하다 junit 을 한 번 사용해 볼까..

developyo.tistory.com

반응형