이 글은 이동욱 님의 스프링 부트와 AWS로 혼자 구현하는 웹 서비스를 읽고 정리한 글입니다.
내용보다 중요한 점, 추가적으로 알아본 것 등을 위주로 적었습니다.
http://www.yes24.com/Product/Goods/83849117
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - YES24
가장 빠르고 쉽게 웹 서비스의 모든 과정을 경험한다. 경험이 실력이 되는 순간!이 책은 제목 그대로 스프링 부트와 AWS로 웹 서비스를 구현한다. JPA와 JUnit 테스트, 그레이들, 머스테치, 스프링
www.yes24.com
많은 사람들의 리뷰, 추천으로 이 책을 정리하려 한다.
스프링부트의 기본을 알고, 그것을 통해 AWS를 접하고자 하는 사람에게 좋을 것 같아서 이 책으로 결정했다.
02장. 스프링 부트에서 테스트 코드를 작성하자
테스트 코드 소개
TDD
TDD는 Test Driven Development의 약자로 ‘테스트 주도 개발’이라고 한다.
외부의 요구 조건이 많이 바뀔 경우, 팀원이 많은 경우 등 보다 탄탄하게 코드를 짜야 하는 경우에 이러한 개발을 한다.
애초에 테스트 코드까지 2개의 코드를 짜야하니 생산성이 떨어지지만, 나중이 편해진다.
http://clipsoft.co.kr/wp/blog/tddtest-driven-development-%EB%B0%A9%EB%B2%95%EB%A1%A0/
TDD(Test-Driven-Development) 방법론 - CLIPSOFT
작성자 : 강성웅 부장 TDD(Test-Driven-Development) 방법론에 대하여… - TDD가 무엇 일까? TDD란 Test Driven Development의 약자로 ‘테스트 주도 개발’이라고 한다. 테스트 주도 개발(TDD)은 설계 이후
clipsoft.co.kr
테스트 코드는 왜 짜야 하는가?
백엔드 개발의 경우, 코딩 후 프로그램 실행을 한 뒤 직접 요청을 해서 검증을 했다. 여기서 3가지 문제점이 발생한다.
- 테스트마다 서버를 실행해야 한다.
만약, 코드를 리펙토링한 후 테스트해야 하는 케이스가 만 단위를 넘어가면 어떻게 될까? 한 케이스마다 서버를 올렸다 내렸다, 번거로움의 연속이다. 서버를 직접 실행하지 않고, 단위 테스트 코드를 작성해야 한다.
- 직접 눈으로 검증해야 한다.
로그나 println()등의 함수로 직접 검증해야 한다. 마찬가지로 테스트 케이스가 커지면 큰일난다. 자동검증을 해주는 테스트 코드를 작성해야 한다.
- 개발자가 만든 기능이 보호받지 못 한다.
새로운 기능 때문에 기존의 기능이 작동하지 못하는 경우가 있다면, 기존의 기능을 테스트하는 코드가 있어야 금방 알아차리고 디버깅할 수 있다.
테스트 프레임워크 xUnit
가장 대중적인 테스트 프레임워크인데, 대표적인 프레임워크는 다음과 같다.
- JUnit - Java
- DBUnit - DB
- CppUnit - C++
- NUnit - .net
당연히 우리는 JUnit을 쓸 것이다. 책에선 JUnit4를 썼지만, 나는 JUnit5를 쓰겠다.
Hello Controller 테스트 코드 작성하기
본격적인 코딩 전에, 내장 WAS?
WAS는 Web Application Server, 웹 어플리케이션 서버를 말하는데, 스프링 부트는 별도로 WAS를 두지 않고 내장 WAS인 톰캣을 사용하도록 권장한다. 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있기 때문이다.
성능상 이슈가 있을 수도 있지만 웬만큼 큰 서비스에서도 내장 WAS를 사용해도 될 정도이다.
이제 다음과 같은 코드를 "HelloController.java" 파일에 추가한다.
@RestController public class HelloController { @GetMapping("/hello") public String hello() { return "hello"; } }
그 후, 클래스명에 커서를 두고 Alt + Enter ( Option + Enter )를 통해 테스트 클래스를 생성하면 자동으로 생성해준다.
@ExtendWith(SpringExtension.class) @WebMvcTest(controllers = HelloController.class) 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)); } }
- 테스트 코드의 작성은 협업과 리팩토링 등을 위해 알아보기 쉽게 해야한다. 따라서 함수명을 한글로 설명하듯이 적어도 된다.
- get(), status(), content() 함수는 static으로 import해야 코드와 같이 쓸 수 있다.
- 책과 다른 코드가 몇 있다. 자세한 것은 책의 저자의 블로그에 정리되어 있다.
https://jojoldu.tistory.com/539
(2020.12.16) 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 최신 코드로 변경하기
작년 11월 말에 스프링 부트와 AWS로 혼자 구현하는 웹 서비스를 출판 하였습니다. Spring Boot가 2.1 -> 2.4로, IntelliJ IDEA가 2019 -> 2020으로 오면서 너무 많은 변화가 있다보니, 집필할 때와 비교해 실습
jojoldu.tistory.com
코드는 Controller layer의 코드를 Test한 것이다. 즉, 실제로 서버를 실행시키지 않고 컨트롤러가 잘 작동하는지 보기 위해 가짜(Mock) MVC를 작동시킨 것이다. 시간, 자원 등을 아낀 것이다.
단위 테스트 (Unit Test)는 정말 중요하다. 이에 대해 정리한 게시글이다. 이 글을 보면 우리가 진행한 테스트는 narrow integration test이다.
Spring에서의 Unit Test (단위 테스트) vs Integration Test (통합 테스트)
TDD TDD는 Test Driven Development의 약자로 ‘테스트 주도 개발’이라고 한다. 외부의 요구 조건이 많이 바뀔 경우, 팀원이 많은 경우 등 보다 탄탄하게 코드를 짜야 하는 경우에 이러한 개발을 한다.
morenow.tistory.com
Hello Controller 코드를 롬복으로 전환하기
책에서는 lombok을 사용 설정하는 데에 많은 시간과 페이지를 투자했지만, 경험상 요즘은 dependency에 입력하면 자동으로 되는 것 같아서 건너뛰겠다.
dto에 관한 내용은 다음 게시글을 참고하자. https://studyandwrite.tistory.com/402
[스프링/Spring] DTO는 왜 써야 하나?
1. 고민? DTO(Data Transfer Object)란 계층간 데이터 교환을 위해 사용하는 객체(Java Beans)입니다. 아래 코드를 보면서 DTO는 왜 필요한가에 대해 생각해보겠습니다. * 실제 엔티티 설계의 일부입니다. 위
studyandwrite.tistory.com
web 패키지에 dto 패키지를 추가하고 다음과 같은 파일을 생성한다.
@Getter @RequiredArgsConstructor public class HelloResponseDto { private final String name; private final int amount; }
보이는 어노테이션 2개가 lombok이 제공해주는 어노테이션이다. lombok은 클래스 단위에서 많은 편의 기능을 제공해주는 라이브러리(의존성)이다. lombok이 제공하는 많은 기능들을 정리해 둔 블로그가 많으니 찾아보길 바란다.
위 코드의 @Getter는 변수들의 getter를 자동 생성해주고 (물론 @Setter도 있다) @RequiredArgsConstructor는 필요한 변수들, 즉 final이나 @NotNull이 붙은 변수들 등을 포함한 생성자를 자동생성한다.
위와 같은 방법으로 테스트 코드 파일을 생성하고 다음과 같이 추가했다.
class HelloResponseDtoTest { @Test 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); } }
가장 눈에 띄는 것은 given, when, then이다. 각각 비교할 데이터 준비, 테스트하기, 예상과 같은지 비교 정도로 알아두자. 이런 식으로 하면 체계적이다.
눈여겨봐야 할 함수는 assertThat이다. 이는 assertj의 메소드를 static import한 것이다. 추가적인 라이브러리가 불필요하고 자동완성이 더 지원된다는 점에서 Junit의 그것보다 좋다.
//assertThat을 사용한 경우 assertThat(dto.getName()).isEqualTo(name); //assertThat을 사용하지 않은 경우 if (dto.getName().equals(name) == false) { //예외 처리 }
위 코드를 보면, 밑의 if문을 사용했을 때보다 assertThat을 사용했을 때가 더 알아보기도 쉽고 간편하다.
이제 dto를 사용하는 것도 Controller에 추가해보자.
//HelloController 에 추가한다 @GetMapping("/hello/dto") public HelloResponseDto helloDto(@RequestParam("name") String name, @RequestParam("amount") int amount) { return new HelloResponseDto(name, amount); }
또한 이에 대한 테스트도 테스트 코드를 추가한다.
//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))); }
성공하는 것을 볼 수 있다.
'스프링부트와 AWS로 혼자 구현하는 웹 서비스' 카테고리의 다른 글
08장 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - EC2 서버에 프로젝트를 배포해 보자 (0) | 2023.02.10 |
---|---|
06,07장 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - AWS 서버 와 데이터베이스 환경을 만들어보자 - AWS EC2, RDS (0) | 2023.02.03 |
03장 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 스프링 부트에서 JPA로 데이터베이스 다뤄보자 (0) | 2023.01.20 |
01장 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 인텔리제이로 스프링 부트 시작하기 (0) | 2023.01.13 |