테스트 코드를 작성함으로서 얻는 몇가지 이점입니다.
- 개발 초기단계에 문제를 발견하게 도와줍니다.
- 나중에 코드를 리팩토링하거나 라이브러리 업그레이드를 한 경우 기존 기능이 잘 작동하는지 알 수 있게 해줍니다.
- 기능의 불확실성을 감소시킵니다.
- 단위테스트 자체로 문서를 작성할 수 있습니다.
단위테스트를 사용하면 서버를 올렸다 내렸다 하면서 수정된 기능을 눈와 손으로 직접 확인할 필요가 없습니다.
테스트 코드 작성을 도와주는 프레임워크인 Junit을 사용해 작성해보겠습니다.
자바 폴더에서 새 패키지를 생성하고, 그 아래에 자바 클래스를 생성하겠습니다.
일반적 패키지 명은 프로젝트의 group Id를 사용합니다.
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}
위 코드는 이제 이 프로젝트의 메인클래스가 됩니다.
@SpringBootApplication
어노테이션을 통해 스프링 부트의 자동설정, Bean읽기, 생성을 모두 자동으로 해줍니다.
중요한 점은 이 어노테이션이 있는 위치를 시작으로 설정으로 읽기때문에 항상 이 클래스는 프로젝트의 최상단에 있어야합니다.
SpringApplication.run
를 통해 스프링부트는 내장 WAS를 사용할 수 있게 됩니다.
이 덕분에 스프링부트는 별도의 톰켓을 설치할 필요가 없고, 스프링 부트로 생성된 jar만 실행함으로서 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있습니다.
이제 현재 패키지 하위에 컨트롤러와 관련된 클래스를 담을 새로운 패키지를 생성하고, 컨트롤러 클래스를 만들겠습니다.
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
@RestController
는 컨트롤러를 JSON으로 반환하는 컨트롤러로 만들어줍니다. 이 어노테이션을 클래스 상위에 정의하면 예전에 @ReseponseBody
를 각 메소드마다 선언했던것을 한번에 사용할 수 있게 해줍니다.
GET요청을 받을 수 있도록 @GetMapping("/hello")
를 사용하겠습니다. @RequestMapping(method = RequestMethod.GET)
와 같은 표현입니다.
API를 작성했으니 제대로 작동하는지 테스트를 해보겠습니다.
ALT + ENTER를 누르면 테스트 코드 클래스를 바로 생성할 수 있습니다.
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void hello를_리턴한다() throws Exception {
String hello = "hello";
mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
}
@RunWith(SpringRunner.class)
테스트를 진행할때 Junit에 내ㅑ장죈 실항자가 아닌 SpringRunner라는 실행자를 사용하겠다는 뜻입니다.
즉 RunWith는 스프링 부트테스트와 Junit사이의 연결고리입니다.
@WebMvcTest
web에 집중하여 사용할 수 있는 어노테이션입니다.
이 어노테이션을 사용해야 @Controller @ControllerAdivce를 사용할 수 있습니다.
단 @Sevice, @Component, @Repository는 사용할 수 없게됩니다.
@AutoWired
빈을 주입받습니다.
MockMvc
테스트할 때 사용합니다. 이 클래스를 통해 GET, POST등에 대한 테스트가 가능해집니다.
perform(get("/hello"))
mockMvc를 통해 hello주소로 get요청을 전송합니다.
.andExpect(status().isOk())
결과가 OK 즉, HTTP Header Ststus가 200 인지 검증합니다.
.andExpect(content().string(hello));
응답본문의 결과가 hello인지 검증합니다.
테스트 코드를 실행하면 다음과 같이 통과한 것을 알 수 있습니다.