지나공 : 지식을 나누는 공간

스프링 부트와 AWS로 혼자 구현하는 웹서비스 정리 - Chapter 02 테스트 코드 본문

Tech/Spring Boot

스프링 부트와 AWS로 혼자 구현하는 웹서비스 정리 - Chapter 02 테스트 코드

해리리_ 2021. 1. 5. 16:01

이동욱 님의 '스프링 부트와 AWS로 혼자 구현하는 웹서비스'를 읽고 기록하고 싶은 내용을 적은 글입니다.

 

 

 

1. 코드 외

  • 패키지명은 주로 웹사이트 주소의 역순으로 한다.
  • 절대 수동으로 검증하고 테스트 코드를 작성하지 않는다. 테스트 코드로 먼저 검증한 뒤 정말 못 믿겠다 싶을 때 프로젝트를 실행해서 확인한다.

 

2. 메인 클래스 코드 작성하기

 

메인 클래스 코드

 

Application 클래스는 앞으로 만들 프로젝트의 메인 클래스이다.

 

@SpringBootApplication

스프링부트가 자동설정되게 하는 어노테이션. 스프링 Bean 읽기와 생성을 모두 자동으로 설정한다.

특히, 이 어노테이션이 있는 위치부터 설정을 읽어가므로 이 어노테이션은 항상 프로젝트의 최상단에 위치해야 한다.

 

 

SpringApplication.run()

main 메소드의 SpringApplication.run()을 통해 내장 WAS(Web Application Server)를 실행한다.

내장 WAS는 외부에 WAS를 두지 않고 애플리케이션을 실행할 때 내부에서 WAS를 실행하는 것이다.

따라서, 항상 서버에 톰캣을 설치할 필요가 없고, 스프링 부트로 만들어진 Jar 파일(실행 가능한 Java 패키징 파일)로 실행할 수 있다. 

 

* 외장 WAS보다 내장 WAS를 권장하는 이유?

내장 WAS를 사용하면 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있다.

하지만 외장을 사용한다면 모든 서버가 WAS의 종류와 버전, 설정을 일치시켜야 한다. 새로운 서버가 추가될 때마다 모든 서버가 같은 WAS 환경을 구축해야 하므로 내장 WAS 사용을 권장한다.

 

3. 컨트롤러 작성

 

컨트롤러 작성

 

 

@RestController

- JSON으로 반환하는 컨트롤러로 만들어 준다.

- 각 메소드마다 @ResponseBody를 선언했던 것을 한번에 사용할 수 있게 한다.

 

@GetMapping

- HTTP Method인 GET의 요청을 받을 수 있는 API로 만들어 준다.

- 예전엔 @RequestMappint(Method = RequestMethod.GET)으로 사용되었었다.

 

 

4. 테스트 코드 작성

 

테스트 코드

@RunWith(SpringRunner.class)

- 테스트를 진행할 때 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킨다,

- 여기서는 SpringRunner라는 스프링 실행자를 사용한다.

- 즉 스프링부트 테스트와 JUnit 사이 연결자 역할을 한다.

 

@WebMvcTest

- 여러 스프링 테스트 어노테이션 중 Web(Spring MVC)에 집중할 수 있는 어노테이션

- 선언할 경우 @Cotroller, @ControllerAdvice 등을 사용할 수 있다.

- @Service, @Component, @Repository 는 사용할 수 없다.

- 여기선 컨트롤러만 사용하므로 위 어노테이션을 작성한 것이다.

 

 

통합 테스트는 @SpringBootTest이고, 단위 테스트는 @WebMvcTest, @DataJpaTest, @RestClientTest, @JsonTest 등이 있다. SpringBoot에는 'spring-boot=starter-test'를 제공하고, 여기에는 JUnit5, AssertJ, JsonPath 등의 라이브러리가 포함되어 있다.

 

통합테스트의 경우 실제 운영 환경에서 사용될 클래스들을 통합해서 테스트하는 것으로, 단위 테스트와 같은 기능 검증이 아니라 스프링 프레임워크에서 전체적으로 플로우가 제대로 동작하는지 검증할 때 사용한다. 애플리케이션의 설정과 모든 Bean을 로드하고, 이로 인해 시간이 좀 더 걸린다. 테스트 단위 자체가 커서 디버깅이 어렵다는 점도 있다.

 

@Autowired

- 스프링이 관리하는 Bean을 주입받는다.

 

private MockMvc mvc;

- 웹 API를 테스트할 때 사용한다.

- 스프링 mvc 테스트의 시작점이다.

- 이 클래스를 통해 HTTP GEET, POST 등에 대한 API 를 테스트할 수 있다.

 

mvc.perform(get("/hello"))

- MockMvc를 통해 /hello 주소로 HTTP GET을 요청한다,

- 체이닝이 지원되므로 여러 검증을 이어서 선언할 수 있다.

 

.andExpect(status().isOk());

- mvc.perform의 결과를 검증한다.

- HTTP Header의 Status를 검증한다, (200(OK), 400, 500 등의 상태)

 

.andExpect(content().string(hello))

- mvc.perform의 결과를 검증한다.

- 응답 본문의 내용을 검증한다. 즉, Controller에서 hello"를 리턴하기로 했으니 이게 리턴되었는지 검증한다.

- 뒤에 나오는 assertj에서 제공하는 assertThat과 유사하지만 andExpect는 mvc테스트다. api 테스트 시 사용한다.

 

 

5. 롬복으로 리팩토링하기

 

Dto 생성 후 Lombok 사용

 

@Getter

- 선언된 모든 필드의 get메소드를 생성한다.

 

@RequiredArgsConstuctor

- 선언된 모든 final 필드가 포함된 생성자를 생성한다. (final로 선언된 필드만 포함한 생성자다. )

- final이 없는 필드는 이 어노테이션이 만든 생성자에 포함되지 않는다.

 

 

dto 테스트코드 작성

 

assertThat

- assertj 라는 테스트 검증 라이브러리의 검증 메소드이다.

- 검증하고 싶은 대상을 메소드 인자로 받는다.

- 메소드 체이닝이 지원되므로 isEqualTo와 이어서 쓸 수 있다.

- 여기에 쓰인 assertThat은 Junit의 기본 assertThat이 아니라 assertj의 메소드이다.

 

isEqualTo

- assertj 의 동등 비교 메소드이다.

- assertThat에 있는 갓과 isEqualTo의 값을 비교해서 같을 때만 성공이다.

 

 

* assertj 가 Junit보다 나은 이유

  • CoreMatchers와 달리 추가적으로 라이브러리가 필요하지 않다.
    • Junit의 assertThat은 is()와 같이 CoreMatchers 라이브러리가 필요하다.
  • 자동완성이 좀 더 확실하게 지원된다.
    • IDE에서는 CoreMatchers와 같은 Matcher 라이브러리의 자동완성이 약하다.
       

 

6. dto관련 테스트가 되었으니, Hello Controller에 실제로 추가하기

 

 

롬복 테스트가 되는 것을 확인했따면 @Getter로 get 메소드가 생성되는 것이고 @RequiredArgsConstructor로 생성자가 생성되는 것임을 확인한 것이므로 위처럼 API를 추가한다.

 

@RequestParam

- 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션이다.

- 여기서는 name이라는 이름(@RequestParam("name")으로 넘긴 파라미터 를,

  메소드의 파라미터 name (String name)에 저장한다.

 

 

이제 추가된 /hello/dto API를 테스트하는 코드를 HelloControllerTest에 추가하자.

 

 

param

- API 테스트할 때 사용될 요청 파라미터를 설정한다.

- 값이 String만 허용된다. amount도 String으로 변경했다.

- 날짜나 숫자 등의 데이터를 사용할 때 모두 문자열로 변경해야만 한다.

 

jsonPath

- JSON 응답값을 필드별로 검증할 수 있는 메소드이다.

- $를 기준으로 필드명을 명시한다. (name은 $.name으로 amount는 $.amount로)

 

 

applicaion 실행 후 API 호출 모습

 

728x90
Comments