스프링계의 고전 토비의 스프링을 봐가며 인터넷을 뒤져가며 스프링 프로젝트를 홀로 진행하고 있던 나였다.
테스트라는 기능이 있다는 걸 알고 있었지만 지금 포트폴리오를 위한 프로젝트 완성이 더 중요하였던 나였기에
페이지를 하나씩 만들어 나가느라
테스트 기능을 사용할 여유가 없었다.
그러다가 오늘 데이터베이스에 더미 데이터를 넣을 일이 생겨서
겸사겸사 JUnit 기반 테스트를 진행해보기로 했다.
혹시 참고자료를 찾아 오신분들은 내가 스프링부트로 프로젝트를 만든 것이 아니라
STS에서 Spring Legacy Project로 만든 프로젝트로 공부를 진행하고 있다는 사실을 알고 읽어주시길 바란다.
첫번째 - JUnit 라이브러리 추가
프로젝트 오른쪽 클릭, build path->add Libraries 후 JUnit 선택 버전 고르고 추가.
라이브러리가 제대로 추가되지 않았다면
initializationError를 마주하게 된다. 역으로 말하자면 initializetionError가 뜬다면 라이브러리를 추가!
두번째- spring-test의존성 주입
sprin-test의존성 주입을 pom.xml에 추가한다
세번째 - 테스트를 위한 DAO, VO 및 DB 테이블 작성 등등이 필요하지만 이미 진행하던 프로젝트가 있기에 생략
네번째- 테스트 클래스 작성
package com.bit.webnovel;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.bit.domain.AuthorVO;
import com.bit.persistence.AuthorDAO;
@WebAppConfiguration
@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 AuthorDAOTest {
@Inject
private AuthorDAO authorDAO;
@Test
public void testCreate() throws Exception {
for (int i = 1; 1 <= 1000; i++) {
AuthorVO author = new AuthorVO();
author.setA_name(Integer.toString(i) + "번작가");
author.setA_history(Integer.toString(i) + "번 작가입니다.");
author.setGender("불명");
authorDAO.create(author);
}
}
}
코드를 설명하자면, 일단 나는 AuthorDAO의 기능 자체는 이미 검증되어 있었다. 웹소설 작가들을 입력하고 그것을 불러오고 삭제, 수정이 이루어지는 기본적인 CRUD DAO인데, JSP에서 버튼을 누르는 것으로 모든 작업이 이루어지게끔 완성되어 있었다. 그렇기에 지금 테스트를 통해서 하려는 것은 더미 데이터를 넣는 것이었다. JSP에서 일일이 버튼을 눌려가며 1000개의 더미데이터를 넣느니 테스트를 통해서 넣어보는 게 더 좋았기 때문이다. 그냥 데이터베이스 관리 프로그램을 열어서 추가해도 되는 일이었지만 스프링하면서 테스트를 안 해보는 것도 이상하게만 느껴졌기에 수행해봤다. 코드는 인터넷에 올라와있는 코드를 참고하며 썼는데 몇 가지 문제점이 있었다.
1. appapplicationcontext?
처음 참고한 웹페이지의 코드에서는 appapplicationcontext.xml이라는 파일이 등장했다. 한 번도 본적 없어서 당황했고 어떤 식으로 형성해야하는지도 알 수가 없었다. 구글을 뒤적이면서 대략적으로 내가 가지고 있던 root-context.xml, servlet-context.xml과 비슷한 역할을 한다는 것이나, 위의 내 코드처럼 둘 다 쓰는 걸로 해결이 가능하다는 걸 확인할 수 있었을 뿐이었다. 문제는 저대로 추가해도 지속되었다는 것이었다. Failed to load ApplicationContext라는 오류는 어떻게 봐도 저부분의 문제처럼 보였는데, 그때문에 한 동안 구글링을 해야만 했다. 그러다가 @WebAppConfiguration애너테이션을 추가해보라는 글을 보고 추가했더니 해결되었다. 문제의 원인은 알지 못한 채 해결하니 공부를 더 해야겠다는 생각이 들 뿐이었다. 컨테이너 개념 같은 부분이 무지의 영역인 듯 한데...
2.java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig
오늘만난 버그 중에선 정말 쉬웠던 해결 servlet 3.1.0으로 버전 업!
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
3. org.mybatis.spring.MyBatisSystemException: nested exception is
org.apache.ibatis.exceptions.PersistenceException:
여기까지 오는데 하루 반나절을 소모했다.
테스트 한 번 실행하는데 왜 이렇게 많은 문제가 생기는지 이해할 수가 없었다.
원래 코드는 잘 실행됬으니 테스트는 더 금방금방 되야하는 게 아닌가 하는 생각에서였다.
위의 mybatis 오류 코드를 보고 그 생각은 더 커졌는데, 원본 코드들이 DB랑 연결하는데 아무문제가 없다는데 대체 왜 네가 그래? 라는 생각이 들었다. 그리고 이 생각은 해결의 실마리였다.
mybatis는 분명 내가 잘 이해하고 있는 분야라고 생각했고 여기에서 문제가 생기는 경우 내가 해결할 수 있으리라고 여겼다. 나는 내 코드들을 하나씩 살펴보았다. 그리고 문제를 확인했다.
test파일의 위치와 매핑을 해줄 리소스 파일의 위치를 신경썼어야 했다!
sts에서 test폴더를 기본적으로 만들어주었기에 아무 생각없이 그 자리에 테스트 클래스를 만들었던 걸로 모두 해결되었다고 여긴 게 잘못이었다.
패키지 경로가 전혀 다르게 잡혔으니 그것을 매핑해줄 리소스도 복사해서 옮겨오던가 했어야만 했던 것이다.
나는 authorMapper.xml을 복사해서 test/resources 폴더 위치로 옮겨준 뒤 실행했다. 그 결과는
이렇게 문제가 풀리면 너무 기쁘다.
'스프링' 카테고리의 다른 글
토비의 스프링 - 1.5 스프링IoC (0) | 2021.05.20 |
---|---|
토비의 스프링 - 1.4 제어의 역전 (0) | 2021.05.20 |
토비의 스프링 - 1.3 DAO의 확장 (0) | 2021.05.19 |
토비의 스프링 - 1.2 DAO의 분리 (0) | 2021.05.19 |
토비의 스프링 - 1.1 초난감 DAO (0) | 2021.05.19 |