2 minute read

Updated:

테스트코드란?

  • TDD는 테스트가 주도하는 개발로 테스트 코드를 먼저 작성하는 것부터 시작된다.
    • 항상 실패하는 테스트를 먼저 작성하고
    • 테스트가 통과하는 프로적션 코드를 작성하고
    • 테스트가 통과하면 프로덕션 코드를 리팩토링한다.
  • 단위테스트는 TDD의 첫 번째 단계인 기능 단위의 테스트 코드를 작성하는 것을 말한다.

Hello Controller 테스트 코드 작성하기

Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  • 프로젝트의 메인클래스. @SpringBootApplication으로 인해 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동으로 설정한다.
  • @SpringBootApplication이 있는 위치부터 설정을 읽어가므로 이 클래스는 항상 프로젝트 최상단에 위치해야 한다.
  • SpringApplication.run으로 인해 내장 WAS를 실행한다. 서버에 톰캣을 설치할 필요가 없고, 스프링 부트로 만들어진 Jar 파일로 실행하면 된다.

HelloController.java

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }
}
  • @RestController
    • 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줌
    • @ResponseBody를 메소드마다 선언했던 것을 한번에 사용할 수 있게 해준다.
  • @GetMapping
    • HTTP Method인 Get의 요청을 받을 수 있는 API로 만들어 준다. 예전에는 @RequestMapping(mehtod=RequestMehod.GET)으로 사용되었다.

HelloControllerTest.java

@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)에 집중할 수 있는 어노테이션
    • 선언할 경우 @Controller, @ControllerAdvicd등을 사용할 수 있다.
  • 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)
  • andExpect(content().string(hello))
    • 응답 본문의 내용을 검증한다.

Hello Controller 코드를 롬복으로 전환하기

롬복 설정하기

  • 롬복이란?
    • 자바 개발 시 자주 사용하는 코드 Getter, Setter, 기본생성자, toString 등을 어노테이션으로 자동 생성해주는 라이브러리
  • 롬복을 설정하려면 우선 bulid.gradle에 코드를 추가하고, 롬복 플러그인을 설치한다.(Plugins Action 검색 [ctrl + shift + A])

bulid.gradle

    dependencies {
        compile('org.springframework.boot:spring-boot-starter-web')
        compile('org.projectlombok:lombok')
        testCompile('org.springframework.boot:spring-boot-starter-test')
    }
  • 마지막으로 Enable annotaion processing을 체크한다. (Setting > Build > Compiler > Annotation Processors)

롬복은 프로젝트마다 설정해아 한다. 플러그인 설치는 한번만 하면 되지만, build.gradle에 라이브러리를 추가하는 것과 Enable annotaion processing을 체크하는 것은 프로젝트마다 진행해야 한다.

Hello Controller 기존 코드 롬복으로 변경

HelloResponseDto

@Getter
@RequiredArgsConstructor
public class HelloResponseDto {

    private final String name;
    private final int amount;
}
  • @Getter
    • 선언된 모든 필드의 get 메소드를 생성해준다.
  • @RequiredArgsConstructor
    • 선언된 모든 fianl 필드가 포함된 생성자를 생성해준다.

HelloResponseDtoTest

public class HelloResponseDtoTest {

    @Test
    public void 롬복_기능_테스트(){
        //given
        String name = "test";
        int amount = 1000;

        //when
        HelloResponseDto dto = new HelloResponseDto(name, amount);

        //then
        assertThat(dto.getName()).isEqualTo(name);
        assertThat(dto.getAmount()).isEqualTo(amount);
    }
}
  • asserThat
    • assertj라는 테스트 검증 라이브러리의 검증 메소드
    • 검증하고 싶은 대상을 메소드로 받는다.
    • 메소드 체이닝이 제공되어 isEqualTo와 같이 메소드를 이어서 사용할 수 있다.
  • isEqualTo
    • assertj의 동등 비교 메소드

HelloController.java

    @GetMapping("/hello/dto")
    public HelloResponseDto helloDto(@RequestParam("name") String name,
                                     @RequestParam("amount") int amount){
        return new HelloResponseDto(name, amount);
    }
  • @RequestParam
    • 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션
    • 여기선 외부에서 name @RequestParam(“name”)이란 이름으로 넘긴 파라미터를 메소드 파라미터 String name에 저장하게 된다.

HelloControllerTest

    @Test
    public void helloDto가_리턴된다() throws Exception {
        String name = "hello";
        int amount = 1000;

        mvc.perform(get("/hello/dto").
                param("name", name).
                param("amount", String.valueOf(amount)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name", is(name)))
                .andExpect(jsonPath("$.amount", is(amount)));
    }
  • param
    • API 테스트 시 사용될 요청 파라미터를 설정한다.
    • 단, 값은 String만 가능함. 따라서 숫자/날짜 데이터를 등록할 때는 문자열로 변경해야 함.
  • jsonPath
    • JSON 응답값을 필드별로 검증할 수 있는 메소드
    • $을 기준으로 필드명을 명시함.