이 글은 이동욱 님의 '스프링 부트와 AWS로 혼자 구현하는 웹 서비스' 책 내용을 정리한 것입니다.
TDD의 첫번째 단계인 기능 단위의 테스트 코들르 작성하는 것
TDD와 달리 테스트 코드를 꼭 먼저 작성해야 하는 것 X
리펙토링 포함 X
"순수하게 테스트 코드만 작성하는 것"
자바용 테스트 코드 작성을 도와주는 프레임워크인 JUnit을 사용할 예정.
다음과 같이 패키지를 하나 생성한다.
일반적으로 패키지명은 웹 사이트 주소의 역순으로 함
생성한 패키지 아래에 클래스명이 Application인 자바 클래스를 생성한다.
그리고 다음 코드를 작성한다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //요게 있는 위치부터 설정을 읽어감 = 항상 프로젝트의 최상단에 위치
// 스프링부트의 자동 설정, 스프링 Bean 읽, 생성을 모두 자동으로 설정됨
public class Application { // 메인 클래스
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// SpringApplication.run = 내장 WAS 실행 -> 톰캣 설치할 필요 X
}
}
별도로 외부에 WAS(Web Application Server)를 두지 않고 어플리케이션을 실행할 때 내부에서 WAS를 실행하는 것
➡️ 항상 서버에 톰켓을 설치할 필요가 없게 됨. 스프링 부트로 만들어진 Jar 파일로 실행
스프링부트에서는 내장 WAS를 사용하는 것을 권장하고 있음
"언제 어디서나 같은 환경에서 스프링부트를 배포" 할 수 있기 때문
IF, 외장 WAS를 사용,
모든 서버는 WAS의 종류와 버전, 설정을 일치시켜야함.
새로운 서버가 추가되면 모든 서버가 같은 WAS 환경을 구축해야 한다.
만약 30대의 서버에 설치된 WAS의 버전을 올린다면 -> 큰 작업이 될 수 있음
➡️ 내장 WAS 사용하면 모두 해결 가능함
다음과 같이 web 패키지를 만든다.
위 패키지에는 "컨트롤러"와 관련된 클래스들을 담을 것임
해당 패키지 아래에 HelloController라는 이름의 클래스를 생성하고 아래의 코드를 작성한다.
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";
}
}
자바 개발할 때 자주 사용하는 코드 Getter, Setter, 기본 생성자, toString 등을 어노테이션으로 자동으로 생성해줌
build.gradle에 다음의 코드를 추가하고 Refresh함
implementation('org.projectlombok:lombok')
** 책에는 위처럼 나와있지만 나는 gradle버전 차이 때문에 오류가 났다.
나는 다음의 코드를 추가했다.
implementation 'org.projectlombok:lombok'
testImplementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
라이브러리를 다 받았다면 롬복 플러그인을 설치함
Ctrl+Shift+A로 플러그인 Action을 검색하고
lombok을 검색한 후 설치하면 된다.
설치가 다 되면 Restart IDE를 클릭해서 인텔리제이를 재시작함.
마지막으로는 Enable annotation processing을 체크하면 된다!
롬복을 설치했으니 기존 코드를 롬복으로 리팩토링 해보자!
Web패키지에 dto 패키지를 추가한다.
앞으로 모든 응답 dto는 이 dto 패키지에 추가함
이 패키지에 HelloReponseDto를 생성하고 아래의 코드를 작성한다
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public class HelloResponseDto {
private final String name;
private final int amount;
}
이제, 이 Dto에 적용된 롬복이 잘 작동하는지 간단한 테스트 코드를 작성하자
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);
}
}
실행시키면 다음의 사진과 같이 기능이 정상적으로 수행되는 것을 확인할 수 있다.
롬복의 @Getter로 get 메소드가, @RequriedArgsConstructor로 생성자가 자동으로 생성되는 것이 증명되었다.
그렇다면, HelloController에도 새로만든 ResponseDto를 사용하도록 메소드를 추가해 보자!
다음의 코드를 추가한다.
@GetMapping("/hello/dto")
public HelloResponseDto helloDto(@RequestParam("name") String name,
@RequestParam("amount") int amount) {
return new HelloResponseDto(name, amount);
}
추가된 API를 테스트하는 코드를 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)));
}
정상적으로 통과됨을 확인할 수 있다.
교재를 따라서 코드를 따라치고 있긴 하지만 역시 깊이 있게 이해하는 것은 어려운 것 같다.
사실 테스트 코드를 어떻게 작성해야 하는지, 언제 테스트코드를 작성해서 무엇을 확인해야 하는지 잘 모르겠다.
DTO도 개념도 알고 있고 그게 뭐냐고 물어본다면 대답도 할 수 있지만,
코드에서 어떻게 구현을 하고 내부에서 어떻게 작동하고 있는지에 대한 이해는 부족하다
공부한지 얼마 되지 않아 그런걸까!
일단 해보자는 마음으로 모르는 부분을 얼렁뚱땅 넘어가다보면 계속해서 모르는 부분, 즉 구멍이 생기는 것 같다.
빠르게 책 한권을 끝내되, 대충하지는 말자!