오늘은 Junit을 활용한 컨트롤러 테스트에 대한 내용이다.
책을 보며 스프링을 공부하다 이녀석 때문에 엄청나게 고생을 했다. 나처럼 고생하는 사람들을 위해 이 글을 쓴다.
우선 내 프로젝트의 버전은 아래와 같다.(pom.xml)
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
단위테스트를 위해서 아래와 같이 두 개의 라이브러리가 필요하다.
spring-test
junit
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
이때 spring-test 라이브러리의 버전은 spring 버전과 같은 버전으로 맞춰야 한다!!
그리고 한 가지 중요한 것이 또 있다.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
아마 프로젝트를 생성하면 pom.xml에 servlet-api 라이브러리가 위와 같이 돼 있을 것이다. 하지만 현재 나와 같은 spring 버전을 사용한다면
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency> -->
주석처리나 해당 코드를 삭제한 후 위와 같이 변경해줘야 한다.
가장 먼저 GET 방식으로 전송할 때 컨트롤러의 단위테스트를 진행해 볼 것이다. 디렉토리 구조와 컨트롤러 클래스의 코드는 다음과 같다.
package com.bookBoard.controller;
@Log4j
@Controller
@RequestMapping("/board/*")
public class BoardController {
@Setter(onMethod_ = {@Autowired})
private BoardService bService;
@GetMapping("/list")
public void list() {
log.info("list .................");
List<BoardVO> board = bService.getBoardList();
log.info(board);
}
}
위의 코드를 서버실행 없이 단위테스트를 통해 잘 실행되는지 확인해 볼 것이다. 디렉토리 구조는 다음과 같다.
package com.bookBoard.controller;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"
})
@Log4j
public class BoardControllerTests {
@Setter(onMethod_= {@Autowired})
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
log.info("complete setup!");
}
@Test
public void testList() throws Exception {
mockMvc.perform(get("/board/list"));
}
}
POST 전송의 컨트롤러 코드이다.
package com.bookBoard.controller;
@Log4j
@Controller
@RequestMapping("/board/*")
public class BoardController {
@Setter(onMethod_ = {@Autowired})
private BoardService bService;
@PostMapping("/remove")
public String remove(String bno) {
log.info("remove ...............................");
log.info("delete result : " + bService.deleteBoard(bno));
return "";
}
}
POST 전송 테스트 코드이다.
package com.bookBoard.controller;
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"
})
@Log4j
public class BoardControllerTests {
@Setter(onMethod_= {@Autowired})
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
log.info("complete setup!");
}
@Test
public void testRemove() throws Exception {
mockMvc.perform(post("/board/remove")
.param("bno", "bord0021"));
}
}
testRemove() 메서드에서 get방식에서는 perform() 안에 get()을 사용했지만 지금은 post 방식을 테스트하기 때문에 post()를 사용한다. 또 해당 방식에선 bno라는 파라미터가 필요한데 이를 위해 param이란 메서드를 사용하여 해당 파라미터의 값을 적어주면 된다.
아직 junit을 10분의 1도 안써봤지만 우선 써 본거에 만족중이다 :) 계속 공부하면서 junit의 많은 기능을 써 봐야겠다!
참고1
코드로 배우는 스프링 웹 프로젝트