Blog

[Spring-LDW] 프로젝트 생성과 간단 API 작성 및 테스트 코드 사용해보기

Category
Author
citeFred
citeFred
PinOnMain
1 more property
스프링 부트와 AWS로 혼자 구현하는 웹 서비스  : 인텔리제이, JPA, JUnit 테스트, 그레이들, 소셜 로그인, AWS 인프라로 무중단 배포까지 이동욱 저
1장 인텔리제이로 스프링 부트 시작하기
Table of Content

프로젝트 생성

교재는 인텔리제이 커뮤니티 버전을 사용하지만 나는 교육과정 이후로 인텔리제이 얼티밋 버전의 장점을 확인하고 자비로 결제해서 계속해서 연습에 사용하고 있다. 따라서 이 부분은 나의 환경 설정에 따라 진행하고자 했다.
프로젝트는 Gradle 기반의 스프링 부트 프로젝트로 build.gradle에서 프로젝트에 필요한 다양한 의존성들을 관리 하게 된다.
plugins { id 'java' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.1.4' } group = 'com.citefred' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
Java
복사

repositories부분의 mavenCentral 과 jcenter?

각종 의존성(라이브러리)들은 어떤 원격 저장소에서 받아오게 된다. 그 중 인텔리제이에서 기본적으로 생성되는 것은 mavenCentral이다. 예전에 수동으로 다운로드 받아서 라이브러리를 추가해본적이 있는데
위 링크에서 다운로드 받아서 jar파일을 프로젝트에 임포트하는 과정이었다.
mavenCentral은 이전부터 많이 사용하는 저장소지만, 본인이 만든 라이브러리를 업로드하기 위해서는 정말 많은 과정과 설정이 필요합니다. … 점점 공유가 안 되는 상황이 발생했습니다. 최근에 나온 jcenter는 이런 문제점을 개선하여 라이브러리 업로드를 간단하게 하였습니다..
jcenter는 처음 들어보는 이름이다. 라이브러리를 받아오는 레포지토리를 mavenCentral말고도 jcenter를 사용 할 수 있는 것을 알게 되었다. 당장에 어떤 차이점이 있는지는 불확실하다. 아마 가끔 누락된 라이브러리 등은 jcenter를 통해서 받아 올 수 있을 것 같다. 특히 의존성 버전 호환 관련된 문제는 프로젝트 진행 중 서로 복잡하게 얽혀 있어서 버전과 관련된 문제 등이 발생 할 때 jcenter에 대해서도 인지하고 있어야 할 것 같다.
조금 더 찾아보니 다음과 같은 차이점이 있었다.

jcenter 클로징?

Gradle블로그에 다음과 같은 글이 게시된 것을 확인했다. 이제 사용이 안되는 것인지 기존 jcenter를 사용한 부분에 대해서 mavenCentral로 교체하라는 내용이 포함되어 있다.

dependencies부분

현재는 boot, boot-starter-web, boot-starter-test 로 기본적인 스프링 부트 의존성들이 추가되어 있다. 인텔리제이는 메이븐 저장소의 데이터를 인덱싱해서 관리하기 때문에 의존성 자동완성이 가능하다. ctrl+space
단, 특정 버전을 명시하지 않아야만 맨 위에 plugins 에 작성된 스프링 부트의 버전(id org.springframework.boot' version '3.2.0')과 호환되는 버전이 설치된다.
이렇게 관리하면 라이브러리들의 버전 관리가 한 곳에 집중되고 버전 충돌 문제를 해결 할 수 있다.

인텔리제이에서의 Git과 Github 등록

이 과정은 이미 Github이 연동했기 때문에 생략했다. MacOS기 때문에 Brew를 통해서 Git을 설치하는 과정을 진행해야 한다. 인텔리제이 자체에서 Git, Github를 지원하는 환경이 원활하기 때문에 무리없이 진행 할 수 있다.
아래와 같이 원격 리포지토리를 연결해두었으며 해당 교재의 학습은 커밋을 통해 기록하고 있다. 교재에 나오는 .gradle, build 폴더는 자동적으로 .gitignore에 등록된다. 보통 application.properties는 민감한 정보가 있어서 추적을 제외하기도 하지만 현재는 학습과정으로 그대로 진행했다.
LDW-Spring
yzpocket

기초 API 작성

HelloController.java를 통해 JSON을 반환하는 @RestController 어노테이션을 통해 기초 테스트용 컨트롤러를 구현했다. 단순히 localhost:8080/hello 라는 url을 요청하면 “hello”라는 문자열을 반환, 응답하는 메소드이다.
package com.citefred.ldwspring.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"; } }
Java
복사

기초 API의 테스트 코드 작성

이 교재는 처음부터 TDD의 중요성, 테스트코드의 중요성을 강조하는 듯이 초반 부분부터 테스트 코드 작성의 안내가 나타난다. 다른 강의는 대부분 프로젝트가 어느정도 완성될 때 쯤 실습 할 수 있도록 나타나지만 개발자님이 중요시하는 부분들이 느껴진다. 나 또한 주먹구구식으로 테스트코드를 학습했고, 작성 할 때마다 어려웠던 부분이 있어서 이번 기회에 한번 코드를 잘 살펴보고자 한다.
package com.citefred.ldwspring.web; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.test.web.servlet.MockMvc; 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.status; @ExtendWith(SpringExtension.class) @WebMvcTest(controllers = HelloController.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)); } }
Java
복사

@RunWith(JUnit4)→@ExtendWith(JUnit5)

교재의 코드와 다른 부분은 클래스 선언부의 @RunWith(SpringRunner.class) 라는 어노테이션이 없는 부분이다. 해당 어노테이션은 JUnit4에서 사용되었던 어노테이션으로 아래와 같은 기능을 하는 어노테이션이다.
테스트를 진행 할 때 JUnit에 내장된 실행자 외에 다른 실행자를 실행 시킴
여기서는 SpringRunner라는 스프링 실행자를 사용하도록함
이는 곧 스프링 부트 테스트와 JUnit 사이에 연결자 역할을 해줌
하지만 JUnit5가 사용되고 있으며 본 프로젝트의 스프링 부트 버전과 호환되는 의존성들이 추가되면서 자연스럽게 위 어노테이션을 사용 할 수 없는 문제가 발생했었다. 따라서 검색해본 결과 @ExtendWith(SpringExtension.class) 를 사용하는것으로 변경되었다고 한다. 하지만 내 의존성에는 특별한 버전 명시를 안했기 때문에 어떤 버전의 JUnit이 설치 된지 확인이 필요하다.
좌측 네비게이션에서 External Libraries에는 해당 프로젝트에 설치된 외부 라이브러리들을 모두 살펴 볼 수 있다. 그 중 JUnit 관련 라이브러리들의 버전들은 모두 5.x 버전으로 JUnit5를 사용하고 있음을 알 수 있다.

@WebMvcTest

여러 스프링 테스트 어노테이션 중 Web(Spring MVC)에 집중 할 수 어노테이션
선언 할 경우 @Controller, @ControllerAdvice 등을 사용 할 수 있다.
단, @Service, @Component, @Repository 등은 사용 할 수 없다.
이 말은 @WebMvcTest는 @Controller@RestController@ControllerAdvice 같은 어노테이션이 붙은 Controller 관련 bean들을 대상으로 load해준다. 따라서 Controller 이외의 Service에 대해서는 MockBean을 통해 가짜객체를 주입해야 한다.

@SpringBootTest과의 차이점?

@SpringBootTest의 경우 모든 빈을 로드하기 때문에 테스트 구동 시간이 오래 걸리고, 테스트 단위가 크기 때문에 디버깅이 어려울 수 있다. Controller 레이어만 슬라이스 테스트 하고 싶을 때에는 @WebMvcTest를 쓰는게 유용하다.

private MockMvc mvc;

웹 API를 테스트 할 때 사용
스프링 MVC 테스트의 시작점
이 클래스를 통해 HTTP GET, POST 등에 대한 API 테스트를 할 수 있음
따라서 해당 클래스로 생성한 객체 mvc를 통해서 perform(”URL”)로 API테스트를 할 수 있다. 해당 요청의 결과를 andExpect() 같은 메소드를 사용하여 결과, 응답 상태 등을 검증하여 테스트를 진행한다.
Search
 | Main Page | Category |  Tags | About Me | Contact | Portfolio