テストコードの作成


このプレゼンテーションは、Spring BootとAWSが独自にWebサービスマニュアルに基づいて作成したものです.
1.スプリングガイドにテストコードを書く
1.1テストコードの概要
TDD:テスト主導の開発
ユニットテスト:TDDの最初のステップ
なぜ
  • のテストコードを作成しますか?
    1)クイックフィードバック
    2)自動検証可能
    3)セキュリティ開発者が作成した機能
  • 1.2テストコードの作成
    1.2.1コントローラテスト
    1) Controller
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    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로 만들어줌
    2) ControllerTest
    import org.junit.jupiter.api.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.hamcrest.Matchers.is;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
    
    @RunWith(SpringRunner.class) ⓐ
    @WebMvcTest ⓑ
    public class HelloControllerTest {
    
        @Autowired ⓒ
        private MockMvc mockMvc; ⓓ
    
        @Test
        public void returnHello() throws Exception {
            String hello = "hello";
    
            mockMvc.perform(get("/hello")) ⓔ
                    .andExpect(status().isOk()) ⓕ
                    .andExpect(content().string(hello)); ⓖ
        }
    }
    ⓐ @RunWith(SpringRunner.class)
    - 테스트를 진행할 때 JUnit에 내장된 실행자 외 다른 실행자를 실행시킴
    - 즉, 스프링 부트 테스트와 JUnit 사이에 연결자 역활을 함
    
    
    ⓑ @WebMvcTest
    - 여러 스프링 테스트 어노테이션 중, Web(Spring MVC)에 집중할 수 있는 어노테이션 임
    - 선언할 경우 @Controller, @ControllerAdvice 등을 사용할 수 있음
    - 단, @Service, @Component, @Repository 등은 사용할 수 X
    
    ⓒ @Autowired
    - 스프링이 관리하는 빈(Bean)을 주입 받음
    
    ⓓ private MockMvc mockMvc;
    - 웹 API 테스트할 때 사용
    - 스프링 MVC 테스트의 시작점
    - HTTP GET, POST 등에 대한 api 테스트를 할 수 있음
    
    ⓔ mockMvc.perform(get("/hello")) 
    - MockMvc를 통해 /hello 주소로 HTTP GET 요청을 함
    - 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언할 수 있음
    
    ⓕ .andExpect(status().isOk())
    - mockMvc.perform의 결고를 검증
    - HTTP Header의 Status를 검증
    - 200, 404, 500 등의 상태를 검증
    - isOk : 200 상태인지 검증
    
    ⓖ .andExpect(content().string(hello)); 
    - 응답 본문의 내용을 검증
    - Controller에서 "hello"를 리턴하기 때문에 값이 맞는지를 검증
    1.2.2 rom bookを使用したDTOの作成とテスト
    1) HelloResponseDto
    import lombok.Getter;
    import lombok.RequiredArgsConstructor;
    
    @Getter ⓐ
    @RequiredArgsConstructor ⓑ
    public class HelloResponseDto {
    
        private final String name;
        private final int amount;
    }
    ⓐ @Getter
    - 선언된 모든 필드의 get 메소드를 생성해 줌
    
    
    ⓑ @RequiredArgsConstructor
    - 선언된 모든 final 필드가 포함된 생성자를 생성해 줌
    - final이 없는 필드는 생성자에 포함되지 않음
    2) HelloResponseDtoTest
    import org.junit.Test;
    
    import static org.assertj.core.api.Assertions.assertThat;
    
    public class HelloResponseDtoTest {
    
        @Test
        public void lombokFunctionTest() {
            String name = "test";
            int amount = 1000;
    
            HelloResponseDto dto = new HelloResponseDto(name, amount);
    
            assertThat(dto.getName()).isEqualTo(name); ⓐⓑ
            assertThat(dto.getAmount()).isEqualTo(amount);
        }
    
    }
    ⓐ assertThat
    - assertj라는 테스트 검증 라이브러리의 검증 메소드
    - 검증하고 싶은 대상을 메소드 인자로 받음
    - 메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이어서 사용할 수 있음
    
    
    ⓑ isEqualTo
    - assertj의 동등 비교 메소드
    - assertThat에 있는 값과 isEqualTo의 값을 비교해서 같을 때만 성공
    
    * 해당 교제에서 Junit의 기본 assertThat이 아닌 assertj의 assertThat을 사용함, 해당 장단점은 아래와 같음
     + CoreMatchers와 달리 추가적으로 라이브러리가 필요하지 않음
     + 자동완성이 좀 더 확실하게 지원됨
     
     
     
    3)コントローラはHelloResponseDtoを使用する
        @GetMapping("/hello/dto")
        public HelloResponseDto helloDto(@RequestParam("name") String name ⓐ , @RequestParam("amount") int amount) { 
    	return new HelloResponseDto(name, amount);
        }
    ⓐ @RequestParam
    - 외부에서 API로 넘긴 팔라미터를 가져오는 어노테이션
    - 여기서는 외부에서 name이란 이름으로 넘긴 파라미터를 메소드 파라미터 name에 저장하게됨
    4)ControllerTestでHelloResponseDtoをテストする
    @Test
    public void returnHelloDto() throws Exception {
    	String name = "hello";
    	int amount = 1000;
    
            mockMvc.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 응답값을 필드별로 검증할 수 있는 메소드
    - $를 기준으로 필드명을 명시함