스프링부트에서 테스트 코드를 작성하자

Wintering·2022년 6월 8일
0

테스트코드

TDD : 테스트가 주도하는 개발,
반복테스트를 이용한 소프트웨어 방법론으로 작은 단위의 테스트 케이스를 작성하고 이를 통과하는 코드를 추가하는 단계를 반복하여 구현한다.

  • TDD의 개발주기
    • RED : 항상 실패하는 테스트를 먼저 작성
    • GREEN : 테스트가 통과하는 프로덕션 코드를 작성
    • BLUE : 테스트가 통과하면 프로덕션 코드를 리팩토링하기(Refactor)

      단위테스트 : TDD의 첫 번째 단계, 기능 단위의 테스트 코드를 작성하는 것
    • 단위 테스트는 개발단계 초기에 문제를 발견하게 도와준다.
    • 단위 테스트는 개발자가 나중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르기 작동하는지 확인 가능
    • 단위 테스트는 기능에 대한 불확실성을 감소시킬 수 있음
    • 단위 테스트는 시스템에 대한 실제 문서를 제공. 즉, 단위 테스트 자체가 문서로 사용될 수 있음

테스트 모드 작성을 도와주는 프레임워크

XUnit (Java에서는 JUnit)

: JUnit은 계속하여 개선중이지만, 현재 가장 많이 사용되고 안정성이 높은 버전은 JUnit4


테스트코드 작성해보기

1. 패키지 작성하고 'Application' 이름으로 클래스 생성하기

package com.jojoldu.book.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);
    }
}
  • 이 클래스가 앞으로 생성할 모든 프로젝트들의 메인클래스
  • @SpringBootApplication
    • 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정하게 함
    • 이 어노테이션이 있는 위치부터 설정을 읽어가야하기 때문에 프로젝트의 최상단에 있어야함.
      SpringApplication.run 내장 WAS(Web Application Server)를 실행
    • 다른 WAS의 사용도 가능하지만 가급적 내장 WAS를 사용을 권장하는데 그래야 언제 어디서나 같은 환경에서 스프링부트를 배포 할 수 있기 때문이다.

2.만들어진 패키지에 'web'패키지 새로 만들고 Controller 관련 클래스 모으기

  • @RestController
    • 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줍니다.
    • 예전에는 @ResponseBody를 각 메소드마다 선언했던 것을 한번에 사용할 수 있게 해준다고 생각하면 됨
  • @GetMapping
    • HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어주는 어노테이션
    • 예전에는 @RequestMapping(method=RequestMethod.GET)의 형태로 사용
    • /hello로 요청이 오면 문자열 "hello" 를 반환하게 됨.

3. 작성한 코드와 같은 내용을 src/test/java에 똑같이 작성하기

: WAS를 실행하지 않고, 테스트코드로 검증

  • @RunWith
    • 테스트를 진행할 때 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킨다.
    • 예제에서는 SpringRunner 스프링 실행자를 사용
    • 스프링 부트 테스트와 Junit 사이의 연결자 역할을 한다.
    • (+) JDK9부터 JUnit5가 사용되기 때문에, JDK8의 경우 자동으로 JUnit4가 path에 추가된다.
  • @WebMvcTest
    • 여러 스프링 어노테이션 중 Web(Spring MVC)에 집중할 수 있는 어노테이션
    • 선언할 경우 @Controller, @ControllerAdivce등을 사용 가능
    • 단, @Service, @Component, @Repository는 사용 불가
    • 예제에서는 컨트롤러만 사용할 예정이므로 선언해줌
  • @Autowired
    • 스프링이 관리하는 Bean을 주입받음
    • 예제와는 다르게 컨트롤러 테스트를 위해 Mockmov를 사용하고 싶다면 @AutoConfigureMockmov를 추가해줘야함. 추가하지 않는 경우 @Autowired를 사용할 때 에러가 표시됨
  • 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,404,500등의 상태 검증
    • 해당 구문에서는 OK, 즉 상태가 200인지를 확인함
  • .andExpect(content().string(hello))
    • mvc.perform의 결과 검증
    • 응답 본문의 내용을 검증
    • Controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지를 검증한다.

테스트결과

실제결과


롬복 소개 및 설치

롬복 : 자바 개발시, 자주 사용하는 코드 Getter,Setter,기본생성자,toString 등을 어노테이션으로 자동 생성

build.gradle에 등록
compile('org.projectlombok:lombok')

HelloController 코드를 롬복으로 전환하기

1. web패키지에 dto패키지 추가

  • @Getter
    • 선언 된 모든 필드의 get 메소드를 생성해줌
  • @RequiredArgsConstructor
    • 선언된 모든 final 필드가 포함된 생성자를 생성해줌.
    • final이 없는 필드는 생성자에 포함되지 않음
    • 이 어노테이션을 선언하지 않으면 필드들에 빨간 줄 에러가 생성 됨 (값을 초기화하거나, 생성자를 만들라고)

2. HelloResonseDtoTest 테스트 코드 작성

  • assertThat
    • assertj라는 테스트 검증 라이브러리의 검증 메소드
    • 검증하고 싶은 대상을 메소드 인자로 받는다.
    • 메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이용해서 사용 가능
  • isEqualTo
    • assertj의 동등 비교 메소드
    • assertThat에 있는 값과 isEqaulTo의 값을 비교하여 같을 때만 성공

테스트결과

롬복의 @Getter 로 get메소드가, @RequiredArgsConstructor로 생성자가 자동으로 생성되는 것을 확인

3. HelloController에서 ResponseDto 사용하기

  • @RequestParam
    • 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션
    • 여기서는 외부에서 name(@RequestParam("name"))이란 이름으로 넘긴 파라미터를 메소드 파라미터 name(string name)에 저장하게 됨.

name과 amount는 API를 호출하는 곳에서 넘겨준 값들. 추가된 API를 테스트하는 코드를 HelloControllerTest에 추가해줘야함.

4. HelloControllerTest 수정

is() : import static org.hamcrest.Matchers.is;

  • param
    • API테스트할때 사용될 요청 파라미터를 설정한다
    • 값은 String만 허용되므로, 숫자/날짜등의 데이터를 문자열로 변경해서 등록해야한다.
  • jsonPath
    • JSON응답값을 필드별로 검증할 수 있는 메소드
    • $를 기준으로 필드명을 명시

0개의 댓글