새벽반.. 밀린 스터디 중..
순서대로 따라 가야 하는 것들이 있어서 노랑이로 포인투 줘씀
2.1 테스트 코드 소개
- TDD
- 테스트가 주도하는 개발
- 테스트 코드를 먼저 작성
- 레드 그린 사이클
- 항상 실패하는 테스트를 먼저 작성하고 (Red)
- 테스트가 통과하는 프로덕션 코드를 작성하고 (Green)
- 테스트가 통과하면 프로덕션 코드를 리팩토링한다 (Refactor)
- 단위 테스트
- TDD의 첫 번째 단계인 기능 단위의 테스트 코드를 작성하는 것
- 순수하게 테스트 코드만 작성하는 것
- 테스트 코드의 이점
- 단위 테스트는 개발단계 초기에 문제를 발견하게 도와줍니다
- 단위 테스트는 개발자가 나중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인할 수 있습니다
- 단위 테스트는 기능에 대한 불확실성을 감소시킬 수 있습니다
- 단위 테스트는 시스템에 대한 실제 문서를 제공합니다 == 단위 테스트 자체가 문서로 사용할 수 있습니다
- 추가 이점
- 빠른 피드백 == 톰캣을 올렸다 내렸다 할 필요 X
- 자동 검증 가능 == 수동 검증 필요 X
- 개발자가 만든 기능을 안전하게 보호 == 기존 기능이 잘 작동되는 것을 보장
- 테스트 코드 작성을 돕는 프레임 워크
- JUnit - Java
- DBUnit - DB
- CppUnit - C++
- NUnit - .net
2.2 Hello Controller 테스트 코드 작성하기
- 패키지 생성 , 패키지명은 'group Id' + '.' + '현재 프로젝트명'
- 패키지 속 자바 클래스 생성, 클래스명은 'Application'
- 코드 작성
package com.example.SpringBootAWS;
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으로 인해 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동 설정
- @SpringBootApplication이 있는 위치부터 설정을 읽어가기 때문에 이 클래스는 항상 프로젝트의 최상단에 위치
- SpringApplication.run : 내장 WAS 실행
- 내장 WAS : 별도로 외부에 WAS를 두지 않고 애플리케이션을 실행할 때 내부에서 WAS를 실행하는 것, 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있기 때문에 사용 권
- 항상 서버에 톰캣을 설치할 필요 없고, 스프링 부트로 만들어진 Jar 파일로 실행하면 됨
4. 1번 패키지의 하위 패키지로 '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을 반환하는 컨트롤러로 만듦
- @GetMapping : Method인 Get의 요청을 받을 수 있는 API 생성
5. 테스트 코드로 검사하기 위해 src/test/java 디렉토리에 1번 패키지 생성
6. 'HelloControllerTest' 클래스 생성 후 코드 작성
import com.example.SpringBootAWS.web.HelloController;
import org.apache.catalina.security.SecurityConfig;
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.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
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.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class,
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.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에 집중할 수 있는 어노테이션
- @Controller, @ControllerAdvice 사용 가능
- @Service, @Component, @Repository 사용 불가
- @Autowired
- 스프링이 관리하는 빈을 주입 받음
- private MockMvc mvc
- 웹 API를 테스트할 때 사용
- 스프링 MVC 테스트의 시작점
- mvc.perform(get("/hello"))
- MovkMvc를 통해 /hello 주소로 HTTP GET 요청
- 체이닝 지원
- .andExpect(status().isOk())
- mvc.perform의 결과 검증
- HTTP Header의 Status 검증
- 200, 404, 500 등의 상태 검증
- .andExpect(content().string(hello))
- mvc.perform의 결과 검증
- 응답 본문의 내용 검증
- "hello"의 값이 맞는지 검증
7. HelloControllerTest 파일에서 실행 or Application.java 파일에서 실행
8. localhost:8080/hello 로 접속
- 테스트 코드로 먼저 검증 후, 못 믿겠을 때 프로젝트를 실행해 확인
1.3 롬복 소개 및 설치하기
- 소개
- 자바 개발자들의 필수 라이브러리
- 코드 Getter, Setter, 기본 생성자, toString 등을 어노테이션으로 자동 생성
- build.gradle에 코드추가
implementation('org.projectlombok:lombok')
3. Marketplace에서 LomBok 설치 후 세팅
1.4 Hello Controller 코를 롬복으로 전환하기
- web 패키지 => dto 패키지 추가 => HelloResponseDto 클래스 생성
- 코드 수정
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public class HelloResponseDto {
private final String name;
private final int amount;
}
- @Getter : 선언된 모든 필드의 get 메소드를 생성
- @RequiredArgsConstructor : 선언된 모든 final 필드가 포함된 생성자 생성
3. test => java => com... => dto 패키지 추가 => HelloResponseDtoTest 클래스 생성
4. 코드 수정
import com.example.SpringBootAWS.web.dto.HelloResponseDto;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
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);
}
}
- assertThat
- assertj라는 테스트 검증 라이브러리의 검증 메소드
- 검증하고 싶은 대상을 메소드 인자로 받음
- 메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이어서 사용 가능
- isEqualTo
- assertj의 동등 비교 메소드
- assertThat의 값 == isEqualTo의 값일 때 성공
- assertj의 장점
- CoreMatchers와 달리 추가적인 라이브러리 필요 X
- 자동완성이 확실하게 지원
5. HelloController에 새로 만든 ResponseDto가 사용되도록 코드 추가
@GetMapping("/hello/dto")
public HelloResponseDto helloDto(@RequestParam("name") String name,
@RequestParam("amount") int amount) {
return new HelloResponseDto(name, amount);
}
- @RequestParam : 외부에서 API로 넘긴 파라미터를 가져오는 어노테이션
- name과 amount는 API를 호출하는 곳에서 넘겨준 값들
6. 추가된 API를 테스트하는 코드를 HelloControllerTest에 추가
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 응답값을 필드별로 검증할 수 있는 메소드, $을 기준으로 필드명 명시
끝 !
'Spring > SpringBoot-AWS' 카테고리의 다른 글
[SpringBoot-AWS] Chap05 - 스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기 (0) | 2023.05.10 |
---|---|
[SpringBoot-AWS] Chap04 - 머스테치로 화면 구성하기 (0) | 2023.05.10 |
[SpringBoot-AWS] Chap03 - 스프링 부트에서 JPA로 데이터베이스 다뤄보자 (0) | 2023.03.29 |
[SpringBoot-AWS] Chap 01 - 인텔리제이로 스프링 부트 시작하기 (0) | 2023.03.22 |
[SpringBoot-AWS] SpringBoot AWS 스터디 계획 (0) | 2023.03.22 |