Spring MVC를 어떻게 테스트 해야 할까?

보통 테스트를 입문할 때는 아주 간단한 POJO 클래스를 만들고 한 눈에 이해되는 메소드를 테스트 한다. 대충 메소드 하나에 파라메터 두어 개를 넣고 돌려받은 리턴값을 기대값과 비교…
그러나 (나태한 변명이겠지만) 실무에 이를 적용하는 것은 쉽지 않았다. 수 십 개의 클래스들과 그 안에 꼬여있는 수 백 개의 메소드들.. 특히 Spring MVC를 개발하다보면, controller는 어떻게 테스트 하고, service는 어떻게 테스트 할지, Spring Context는 어떻게 할지, 레거시 플랫폼으로 부터 받아오는 계속 바뀌는 데이터는 어떻게 고려해야 할지 등. 좀 막막하다.

참고

Spring MVC의 context를 깔고 테스트

  • Spring MVC는 Spring Boot처럼 혼자 뚝딱 실행되지 않는다. Tomcat같은 container가 필요한데… 테스트는 어떻게하지?
  • Bean 들은 어떻게 주입하지?
    • @Autowired로 무책임(?)하게 관리해오던 bean들은 그냥 테스트 코드만 덜컥 실행하면 절로 만들어지지 않음
    • 테스트 시작과 함께 Spring context를 불러와야 bean들이 생성됨
      • JUnit으로 테스트 하기
        // Runner 클래스로 Spring환경으로 실행
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration(locations= { "classpath*:applicationContext.xml" })
        public class Tests {}
        
      • TestNG로 테스트 하기
        // AbstractTestNGSpringContextTests 를 상속
        @ContextConfiguration(classes= { ServiceConfig.class })
        public class Tests extends AbstractTestNGSpringContextTests {}
        
    • ContextConfiguration으로 bean이 정의/설정되는 클래스나 XML 스팩들을 지정할 수 있음

Controller와 그냥 Service(Component)테스트

정리

  • Spring test framework를 이용해 context를 로드한 상태로 테스트 수행
  • Controller는 MockMVC로 테스트
  • Service나 다른 bean들은 평범하게 테스트
  • Mock을 이용해 가상의 의존성을 주입하여 테스트 클래스의 로직만 테스트

기타: Gradle로 test 실행

  • (특정 IDE에서만 일어날 수 있는 일이지만) Test 클래스를 그냥 실행(Run)하면 Gradle로 실행됨, 물론 Gradle로 테스트를 수행할 수도 있음
  • Gradle로 실행하게되면 JVM parameter같은 것을 기존 방식으로 전달할 수 없음(뭔가 다른 방법이 있는 듯)