들어가기 전에
하기 포스팅은 스프링 부트와 AWS로 혼자 구현하는 웹 서비스(이동욱 저)를 공부하여 작성한 내용입니다.
단위 테스트의 장점
- 단위 테스트는 개발 단계 초기에 문제를 발견하게 도와줍니다.
- 단위 테스트는 개발자가 나중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인할 수 있습니다(예: 회귀 테스트).
- 기존에 만든 단위 테스트를 통해 기존 기능에 문제가 생겼는지 빠르게 확인이 가능합니다.
- 단위 테스트는 기능에 대한 불확실성을 감소시킬 수 있습니다.
- 단위 테스트는 시스템에 대한 실제 문서를 제공합니다. 즉, 단위 테스트 자체가 문서로 사용할 수 있습니다.
테스트 코드 작성을 도와주는 프레임워크들 중 가장 대중적인 프레임워크는 xUnit입니다. 이는 개발환경(X)에 따라 Unit 테스트를 도와주는 도구라고 생각하면 됩니다.
- JUnit - JAVA
- CppUnit - C++
현재 아직 많은 회사에서 JUnit5 대신 JUnit4를 사용하므로, 여기서는 JUnit4를 사용해보도록 하겠습니다.
Hello Controller 테스트 코드 작성하기
먼저, 만들어진 프로젝트 내에서 패키지를 하나 생성해보겠습니다.
IntelliJ 프로젝트 생성과 관련된 내용은 하기 포스팅을 참고하면 됩니다.
earth-95.tistory.com/78?category=944016
먼저, Java 디렉토리를 마우스 오른쪽 버튼으로 클릭하여, [New > Package]를 선택한 후 패키지명을 적어줍니다. 현재 groupId를 com.earth.study로 해둔 터라, 해당 패키지명은 com.earth.study.springboot로 지정했습니다.
생성한 패키지 아래에 Java 클래스를 생성해보겠습니다. [New > Java Class]를 선택한 후 Application 클래스를 생성합니다.
클래스 코드는 아래와 같이 작성합니다.
package com.earth.study.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- Application 클래스는 앞으로 만들 프로젝트의 메인 클래스가 됩니다.
- @SpringBootApplication으로 인해 스프링 부트의 자동 설정, spring bean 읽기 및 생성을 모두 자동으로 설정됩니다.
- @SpringBootApplication 어노테이션 위치부터 설정을 읽어가므로, 이 클래스는 항상 프로젝트 최상단에 위치해야 합니다.
- main 메소드 내의 SpringApplication.run을 통해 내장 WAS인 tomcat이 실행됩니다.
- 내장 WAS란 별도로 외부에 WAS를 두지 않고 어플리케이션을 실행할 때 내부에서 WAS를 실행하는 것을 의미합니다.
- 이렇게 되면, 서버 내 tomcat을 설치할 필요 없이, 스프링부트로 만들어진 Jar 파일로 실행하게 됩니다.
왜 내장 WAS를 권장할까?
외장 WAS 역시 사용할 수 있지만, 내장 WAS를 권장하는 이유는 '언제 어디서나 같은 환경에서 스프링 부트를 배포'할 수 있기 때문입니다. 외장 WAS를 쓴다고 하면, 모든 서버는 WAS의 종류와 버전, 설정을 일치시켜야만 합니다. 새로운 서버가 추가될 경우 모든 서버가 같은 WAS 환경을 구축해야 합니다. 하지만, 내장 WAS를 사용하게 되면 그러한 이슈 없이 바로 설치가 가능합니다.
이제는 테스트를 위한 Controller를 생성해보도록 하겠습니다. 현재 패키지 하위에 web이란 패키지를 만들어 보겠습니다. 위에서 만든 패키지를 선택한 후 마우스 오른쪽 버튼을 클릭하여 [New > Package]를 선택합니다.
web 패키지 안에는 컨트롤러와 관련된 클래스를 모두 담을 예정입니다. 이제 테스트해볼 컨트롤러를 만들어보도록 하겠습니다. 위에서 컨트롤러를 만들때와 마찬가지로 패키지를 오른쪽 버튼으로 클릭해 [New > Java Class]를 선택합니다. 이번에 만들 컨트롤러 이름은 HelloController로 하겠습니다.
컨트롤러까지 생성이 완료되었으면, API를 만들어보겠습니다.
package com.earth.study.springboot.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
- @RestController
- 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줍니다.
- @ResponseBody를 각 메소드마다 선언했던 것을 한 번에 사용할 수 있게 해준다고 보면 됩니다.
- @GetMapping
- HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어줍니다.
- 예전에는 @RequestMapping(method = RequestMethod.GET)으로 사용되었습니다.
- 위 코드에서는 /hello로 요청이 오면 문자열 hello를 반환하는 기능을 가지게 되었습니다.
위에서 작성한 코드가 제대로 작동하는지 테스트 코드를 작성하여 확인해보도록 하겠습니다. WAS를 실행하지 않고, 테스트 코드로만 검증을 해보도록 하겠습니다.
먼저, src/test/java 디렉토리에 앞서 생성한 패키지를 그대로 생성합니다. 이때, 클래스명의 경우 대상 클래스 이름에 Test를 붙입니다. 즉, HelloController는 HelloControllerTest로 생성합니다.
생성된 HelloControllerTest 클래스에는 하기와 같이 테스트 코드를 추가합니다.
package com.earth.study.springboot.web;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string(hello));
}
}
- @RunWith(SpringRunner.class)
- 테스트를 진행할 때 JUnit에 내장된 실행자 외 다른 실행자를 실행시킵니다.
- 여기서는 SpringRunner라는 스프링 실행자를 사용합니다.
- 즉, 스프링 부트 테스트와 JUnit 사이 연결자 역할을 합니다.
- @WebMvcTest
- 여러 스프링 테스트 어노테이션 중, Web(Spring MVC)에 집중할 수 있는 어노테이션입니다.
- WebMvcTest로 선언할 경우 @Controller, @ControllerAdvice 등을 사용할 수 있습니다.
- 단, @Service, @Component, @Repository 등은 사용할 수 없습니다.
- 여기서는 컨트롤러만 사용하기 때문에 선언
- @Autowired
- 스프링이 관리하는 빈(Bean)을 주입 받습니다.
- private MockMvc mvc
- 웹 API를 테스트할 때 사용합니다.
- 스프링 MVC 테스트의 시작점입니다.
- 이 클래스를 통해 HTTP GET, POST 등에 대한 API 테스트를 할 수 있습니다.
- mvc.perform(get("/hello"))
- MockMvc를 통해 /hello 주소로 HTTP GET 요청을 합니다.
- 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어 선언할 수 있습니다.
- .andExpect(status().isOk())
- mvc.perform의 결과를 검증합니다.
- HTTP Header의 Status를 검증합니다.
- 여기서는 200인지 아닌지 체크합니다.
- .andExpect(content().string(hello))
- mvc.perform의 결과를 검증합니다.
- 응답 본문의 내용을 검증합니다.
- Controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지 검증합니다.
위 코드가 모두 작성되면, 테스트 코드 옆 ▶을 클릭하여 실행해볼 수 있습니다.
테스트 결과는 하단 사진과 같이Tests passed에 1 of 1 test를 통해 이 테스트를 통과했음을 확인할 수 있습니다.
테스트 코드로 검증을 하였지만, 결과가 믿음직스럽지 않다면 실제로 Application.java 파일로 이동해서 main 메소드의 왼쪽 화살표 버튼을 클릭해 실제로 코드를 실행해 볼 수 있습니다.
실제 코드를 실행하게 되면 아래와 같이 내장 WAS인 tomcat 서버거 8080포트로 실행되었다는 것을 확인할 수 있습니다.
현재, Application.java에서 실행하는 컨트롤러에서 /hello를 호출했을 때 hello가 화면에 찍히도록 소스를 작성했으므로 브라우저상에서 localhost:8080/hello 호출하여 결과를 확인해볼 수 있습니다.
이렇게 수동으로 확인하는 것은 테스트 코드로 먼저 검증한 후 정말 못 믿겠다는 생각이 들 경우에 진행해야 합니다. 그래야만 견고한 소프트웨어를 만드는 역량을 가질 수 있습니다.
'FRAMEWORK > Spring' 카테고리의 다른 글
[SpringBoot] 게시판 만들기 v2.1 (등록/수정/조회 API 만들기) (0) | 2021.04.25 |
---|---|
[SpringBoot] JPA로 데이터베이스 다루기 (0) | 2021.04.24 |
[SpringBoot, PostgreSQL] myBatis ?(물음표) 문자 사용하기 (0) | 2021.02.02 |
[SpringBoot] 게시판 구현하기 21 (스프링 Cloud Config 사용하기) - 미완 (1) | 2021.01.28 |
[SpringBoot] 게시판 구현하기 20 (스프링 프로파일 적용하기) (0) | 2021.01.11 |