Spring Controller Junit test 하기

시작하기

스프링 MVC 프로젝트에서 spring-test 라이브러리를 사용하면 WAS없이 컨트롤러의 동작을 테스트 할 수 있다. 즉, was 구동 없이 존재하는 controller에 request를 만들어 날리는 테스트 로직을 만들어 수행 시킬 수 있다.

개발시 화면동작을 테스트 하기 위해 브라우저에서 수많은 파라미터를 수작업으로 반복 입력하는 경우가 많은데, spring-test 라이브러리르 사용하여 Junit테스트로 Controller를 검사한다면 적어도 벡엔드 컨트롤러에 대한 노가다 테스트를 피할수 있다.

Spring Controller test 코드 만들기

/src/test/java 경로에 SampleControllerTest.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
package org.hanumoka.web;

import javax.inject.Inject;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(
locations ={"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
public class SampleControllerTest {

private static final Logger logger = LoggerFactory.getLogger(SampleControllerTest.class);

@Inject
private WebApplicationContext wac;
private MockMvc mockMvc;

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
logger.info("setup............");
}

@Test
public void testDoA() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.get("/doA"));
}

}

위 파일을 Junit으로 동작 시켰을때, was의 기동 없이 스프링프로젝트의 /doA 컨트롤러에 get 방식 리퀘스트 테스트를 한다.

하지만 아래처럼 오류가 발생할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ERROR: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5d5eef3d] to prepare test instance [org.hanumoka.web.SampleControllerTest@7fac631b]
java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig
at org.springframework.test.context.web.AbstractGenericWebContextLoader.configureWebResources(AbstractGenericWebContextLoader.java:201)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:128)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:61)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)

위 오류가 나는 이유는 servlet-api의 버전이 안맞기 때문이다.
pom.xml에서 servlet-api라이브러리를 아래 javax.servlet-api 최신 버전으로 교체 한뒤 테스트를 하면 정상 동작을 확인 할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- Servlet : 구버전 라이브러리를 주석 처리 -->
<!--
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
-->

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<!-- 최신 라이브러리 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>

spring controller junit request 테스트 결과