1. Spring Boot 3 개발 환경 개선
본격적으로 Spring Boot 3 server를 구성하기 전에 개발 환경을 수정한다.
1-1. build.gradle 수정
build.gradle의 기존 내용에 [그림 1-1]의 내용을 추가한다.
Spring Data JPA library는 Spring Boot 전용 JPA library이다.
H2 library는 local 및 test 환경에서 In-Memory Database의 data를 객체화하여 작업을 수행할 수 있는 환경을 지원한다.
Lombok library는 반복되는 method 작성 작업을 최소화하는 절차를 제공한다.
1-2. templates directory 생성
HTML과 같은 view를 저장하기 위해 main/resources/ 경로에 templates directory를 생성한다.
1-3. application.yml 생성
Spring Boot 관련 설정을 처리하는 application.yml을 main/resources/ 경로에 application.yml을 생성한다. Spring Boot server 실행 시 본 file이 자동으로 load된다.
2. Spring Boot 3의 핵심 구조
Spring Boot 3는 Presentation, Business, 그리고 Persistent layer로 나뉘어져 있다. 각 계층은 독립적으로 기능을 수행하며 서로 query를 주고 받으며 타 계층에 영향을 미치지 않는다.
2-1. Presentation Layer
Presentatoin Layer는 수신한 HTTP 요청을 Business layer로 전송한다. Controller가 본 역할을 수행하며, 여러 개가 존재할 수 있다.
main/java/[package]/ 경로의 TestController.java의 기존 내용을 삭제하고 [그림 2-1]의 내용을 작성한다. TestService instance는 Bean으로써 선언되었다.
2-2. Business Layer
Business layer는 data에 대해 이루어지는 처리 과정이 정의된 business logic 수행을 담당한다. Service가 본 역할을 수행한다.
main/java/[package]/ 경로에 TestService.java를 생성 후 [그림 2-2]의 내용을 작성한다. MeberRepository instance는 Bean으로써 선언되었다. List의 findAll() method는 List 내의 모든 element를 반환한다.
2-3. Persistent Layer
Persistent layer는 database 관련 logic을 처리한다. 이 과정에서 database와 상호작용하는 DAO 객체를 사용할 수 있다. Repositery가 본 역할을 수행한다.
main/java/[package]/ 경로에 Member.java를 생성 후 [그림 2-3]의 내용을 작성한다.
2-4. Mapping Interface
member Table과 Member class를 mapping하기 위한 interface를 정의하기 위해, main/java/[package]/ 경로에 MemberRepository.java를 생성 후 [그림 2-4]의 내용을 작성한다.
3. Run to Test
[2]에서 구현한 layer class들이 정상적으로 작동하는지 test한다.
3-1. data.sql 생성
main/resources/ 경로에 data.sql을 생성 후 [그림 3-2]의 내용을 작성한다.
Application 종료 시 이전에 수동적으로 입력된 data가 사라지는 In-Memory database의 휘발성으로 인한 문제점이 있다. 이때 미리 정의한 data.sql을 통해 applicatoin 실행 시 자동으로 data가 입력된다.
3-2. application.yml 작성
[1-3]에서 생성한 main/resources/application.yml에 [그림 3-3]의 내용을 작성한다.
show-sql 및 format_sql 구문은 application 실행 과정 중 database에 query 요청 시 모든 실행 구문을 표시한다.
defer-datasource-initialization 구문은 application 실행 시 table 생성 및 data.sql의 query를 실행한다.
3-3. Postman으로 HTTP 요청
Application 실행 후 Postman으로 "http://localhost:8080/test" 내용의 HTTP 요청을 전송한다.
4. Test Code
Test code는 작성된 code가 정상적으로 작동하는지 확인할 목적으로 수행된다. 본 기능을 통해 기존 code를 수정할 필요가 없으며 유지보수에 좋다.
4-1. Given-When-Then Pattern
Test Code를 구성하는 방식 중 Given-When-Then Pattern을 채택하여 code를 작성한다.
Given은 test 실행을 준비하는 단계, When은 test를 진행하는 단계, 그리고 Then은 test 결과를 검증하는 단계이다.
4-2. JUnit
JUnit은 Java의 Unit Test Framework이다. Unit Test는 code가 의도대로 작동하는지 unit으로써 검증하는 과정이며, unit은 보통 method이다.
Junit의 이점으로 test 방식을 구분할 수 있는 Annotation을 제공하며, 사용 방법이 간편하다. 또한 자동으로 실행되는 결과에 대해 즉각적인 feedback을 제공한다.
4-2-1. JUnit Test Code 작성
src/test/java/ 경로에 JUnitTest.java를 생성 후 [그림 4-2]의 내용을 작성한다. @Test Annotation을 method 위에 선언하므로써 해당 method가 Test Unit임을 정의한다.
JUnitTest.java 실행 시 console에 [그림 4-3-1]의 결과가 표시된다. 만약 [그림 4-2]에서 int로 선언된 변수 b에 3을 할당 후 재실행하면, [그림 4-3-2]의 결과가 x 표시와 함께 도출된다.
또한 JUnit은 test case가 하나 이상 실패하면 전체 test case가 실패한 것으로 간주한다.
4-2-2. 더 많은 Annotation
src/test/java/ 경로에 JUnitCycleTest.java를 생성 후 [그림 4-4]의 내용을 작성한다. 각 Annotatoin은 다음 의미를 가진다:
1. @BeforeAll: 전체 test case 수행 전 처음 한 번만 실행 / 실행 주기에서 한 번만 호출되므로 static으로 선언
2. @BeforeEach: 각 test case 수행 전에 실행
3. @AfterAll: 전체 test case 종료 전 한 번만 실행 / 실행 주기에서 한 번만 호출되므로 static으로 선언
4. @AfterEach: 각 test case 종료 전 실행
JunitCycleTest.java 실행 시 [그림 4-5]의 결과가 출력된다.
4-3. AssertJ
AssertJ는 JUnit과 함께 사용하여 검증문의 가독성을 높이는 library이다.
[그림 4-6-1]의 기존 JUnit의 method에서 기댓값과 비굣값을 구분하기 어려우나, [그림 4-6-2]의 AssertJ의 method에서 기댓값과 비굣값을 구분하기 비교적 쉽다. AssertJ에 이와 같은 가독성 높은 method가 여러 존재한다.
4-4. TestController.java Test하기
TestController.java 내 class명에 cursor를 위치 후 표시되는 창에서, [More Action]을 선택하면 [그림 4-7-1]의 창이 표시된다.
[Create Test] 선택 시 [그림 4-7-2] 창이 표시되며 제목이 자동으로 생성된다.
[OK] 선택 후 src/test/java/[package]/ 경로를 선택하여 Test file을 생성한다.
TestControllerTest.java에 [그림 4-8]의 내용을 작성한다.
@SpringBootTest Annotation은 @SpringBootApplication Annotation이 존재하는 class 내 Bean을 탐색 후 test용 Application Context를 생성한다.
@AutoConfigureMockMvc Annotation은 MockMvc를 생성하고 자동 구성을 수행한다. MockMvc는 application을 server에 배포하지 않고도 test용 MVC 환경을 만들어 요청 및 전송, 그리고 응답 기능을 제공하는 Utility Class이다. Controller Test 시 사용된다.
Class의 기본 생성자와 Getter 및 Setter를 자동으로 정의하는 Lombok Plugin을 설치한다.
본 class 내에 [그림 4-10]의 내용을 추가한다.
1. perform() method는 요청을 전송하여 결과로 ResultActions 객체를 받는데, 이때 해당 객체는 andExpect() method로 반환값을 검증한다.
2. andExpect() method는 응답을 검증한다. 본 code에서 isOk() method를 사용하여 status 200 응답을 검증한다.
3. accept() method는 요청 시 어떤 type으로 응답을 받을지 정의하는 method이다. 본 코드에서 JSON을 정의했다.
4. jsonPath("$[i].${field}")은 JSON 응답 내 i번 째 field 값을 가져온다.
본 java 실행 시 test 결과가 성공적으로 수행되었음을 확인한다.
'WINK-(Web & App) > Spring Boot 스터디' 카테고리의 다른 글
[2024 Spring Boot 스터디] 정호용 #2 주차 - 스프링부트 구조 이해 및 테스트 (0) | 2024.05.28 |
---|---|
[2024 Spring Boot 스터디] 유태근 #2 주차 - 스프링 컨테이너와 스프링 빈 (0) | 2024.05.27 |
[2024 Spring Boot 스터디] 정성원 #2 주차 - 스프링 컨테이너 (1) | 2024.05.27 |
[2024 Spring Boot 스터디] 남윤찬#2 주차 - 4~5 섹션 (0) | 2024.05.27 |
[2024 Spring Boot 스터디] 황수민 #2 주차 3~4장 (0) | 2024.05.19 |