![article thumbnail image](https://blog.kakaocdn.net/dn/czvqG4/btrlsiHDW5g/oQLv79K1eKFkqOYqCXGQUK/img.png)
1장에서 만든 프로젝트로 패키지를 하나 생성한다.
java 디렉터리를 마우스 오른쪽 버튼 클릭, [New -> Package]를 차례로 선택해서 생성.
일반적으로 패키지명은 웹 사이트 주소의 역순.
그래서 com.tistory.roobi-story.springboot로 생성.
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/021.gif)
그런데 여기서 문제가 발생했다!!
package로 만들었기 때문에 폴더 그림에 .이 있어야 java class를 생성할 수 있는데 .모양이 없으니까 java class파일을 생성할 수가 없다.
무엇이 문제일까 열심히 구글링을 해보았지만 나오는 게 없었다.
폴더가 빨간색, 파란색 바꾸는 것만 찾게 되었다.
혹시나 색상이 저렇게 빨간색으로 바뀌었다면 오른쪽 마우스 클릭 -> mark directory as -> sources root로 설정
무엇이 문제인지 고민의 고민을 하던 중
혹시 특수문자인 - 때문에 그런 건가 싶어서 지우고 새로 만들었다.
그랬더니 package 폴더에 .이 생겼다. <- java class를 생성할 수 있다!
![](https://t1.daumcdn.net/keditor/emoticon/friends2/large/007.png)
package 명에는 하이픈(-)을 사용할 수 없다.
아마도 이와 같은 현상을 경험해본 적이 없으신 분들도 많으실 텐데 블로그를 만들 때 하이픈을 추가했기 때문에 이렇게 했더니 이런 경우에는 하이픈을 빼주시면 된다.
다시 돌아가서
java class명은 Application으로 생성해준다.
// class 코드 작성
package com.tistory.roobistory.springboot;
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이 있는 위치부터 설정을 읽어가기 때문에 이 클래스는 항상 프로젝트의 최상단에 위치해야만 한다.
main 메서드에서 실행하는 SpringApplication.run으로 인해 내장 WAS(Web Application Server)를 실행한다.
내장 WAS란 별도로 외부에 WAS를 두지 않고 애플리케이션을 실행할 때 내부에서 WAS를 실행하는 것을 이야기한다.
장점 : 항상 서버에 톰캣(Tomcat)을 설치할 필요가 없게 되고, 스프링 부트로 만들어진 Jar파일(실행 가능한 java 패키징 파일)로 실행하면 된다.
꼭 스프링 부트에서만 내장 WAS를 사용할 수 있는 것은 아니지만 스프링 부트에서는 내장 WAS를 사용하는 것을 권장하고 있다.
그 이유는 언제 어디서나 같은 환경에서 스프링 부트를 배포할 수 있기 때문이다.
외장 WAS를 사용하면 모든 서버는 WAS의 종류와 버전, 설정을 일치시켜야 한다. 새로운 서버가 추가되면 모든 서버가 같은 WAS 환경을 구축해야 한다. 이게 1대면 다행이지만, 30대 이상의 서버에 설치된 WAS의 버전을 올린다고 하면 실수할 여지도 많고, 시간도 많이 필요한 큰 작업이 될 수 있다. 하지만 내장 WAS를 사용할 경우 이 문제를 모두 해결할 수 있다. 그래서 많은 회사에서는 내장 WAS를 사용하도록 전환하고 있다.
이제 테스트를 위한 Controller를 생성할 것이다.
현재 패키지 하위에 web이라는 패키지를 만든다.
new -> package
package 이름은 web.
앞으로 컨트롤러와 관련된 클래스들은 모두 이 패키지에 담을 것이다.
web Package가 생성되었으면 java class를 생성한다. 이름은 HelloController이다.
생성되었으면 간단한 API를 작성한다.
package com.tistory.roobistory.springboot.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어준다.
public class HelloController {
@GetMapping("/hello") // HTTP Method인 Get의 요청을 받을 수 있는 API를 만들어 준다.
public String hello() {
return "hello";
}
}
// 예전에는 @RequestMapping(method = RequestMethod.GET)으로 사용되었다.
// 이제 이 프로젝트는 /hello로 요청이 오면 문자열 hello를 반환하는 기능을 가지게 되었다.
테스트를 위해서 WAS를 실행하지 않고, 테스트 코드로 검증.
src/test/java 디렉토리 앞에서 생성했던 패키지를 그대로 다시 생성해본다.
일반적으로 테스트 클래스는 대상 클래스 이름에 Test를 붙인다. 그러므로 HelloControllerTest로 생성한다.
생성된 클래스에 다음과 같은 테스트 코드를 추가한다.
package com.tistory.roobistory.springboot;
import com.tistory.roobistory.springboot.web.HelloController;
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.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
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;
@RunWith(SpringRunner.class)
// 테스트를 진행할 때 JUnit에 내장된 실행자 외에 다른 실해자를 실행시킨다.
// 여기서는 SpringRunner라는 스프링 실행자를 사용한다.
// 즉, 스프링 부트 테스트와 JUnit 사이에 연결자 역할을 한다.
@WebMvcTest(controllers = HelloController.class)
// 여러 스프링 테스트 어노테이션 중 Web(Spring MVC)에 집중할 수 있는 어노테이션이다.
// 선언할 경우 @Controller, ControllerAdvice 등을 사용할 수 있다.
// 단, @Service, @Component, @Repository 등은 사용할 수 없다.
// 여기서는 컨트롤러만 사용하기 때문에 선언.
public class HelloControllerTest {
@Autowired
// 스프링이 관리하는 빈(Bean)을 주입 받는다.
private MockMvc mvc;
// 웹 API 테스트할 때 사용한다.
// 스프링 MVC 테스트의 시작점.
// 이 클래스를 통해 HTTP GET, POST 등에 대한 API 테스트를 할 수 있다.
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
mvc.perform(get("/hello"))
// MockMvc를 통해 /hello 주소로 HTTP GET 요청을 한다.
// 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언할 수 있다.
.andExpect(status().isOk())
// mvc.perform의 결과를 검증한다.
// HTTP Header의 status를 검증한다.
// 흔히 알고 있는 200, 400, 500 등의 상태를 검증한다.
// 여기서는 OK 즉 200인지 아닌지를 검증한다.
.andExpect(content().string(hello));
// mvc.perform의 결과를 검증한다.
// 응답 본문의 내용을 검증한다
// Controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지 검증한다.
}
}
코드 작성 후 테스트 코드를 실행해본다. (메소드 왼쪽의 화살표를 클릭)
하단에 Tests passed라고 뜨면 테스트에 통과한 것이다.
검증용으로 선언했던 .andExpect(status().isOk())와 .andExpect(content().string(hello)가 모두 테스트를 통과했음을 의미한다.
테스트코드로 검증했지만 아직 의심이 든다면 수동으로 실행해서 값이 어떻게 출력되는지 확인해본다.
Application.java 파일로 이동해서 마찬가지로 main 메소드의 왼쪽 화살표 버튼을 클릭한다.
톰캣 서버가 8080포트로 실행되었다는 것도 로그에 출력된다.
실행이 끝났다면 웹브라우저를 열어 localhost:8080/hello로 접속해본다.
그러면 문자열 hello가 잘 노출됨을 확인할 수 있다.
테스트 코드의 결과가 같은 것을 알 수 있다. 이후에도 테스트 코드는 계속 작성한다.
브라우저로 한번씩 검증은 하되 테스트 코드는 꼭 따라 해야 한다. 그래야 견고한 소프트웨어를 만드는 역량이 성장할 수 있다. 추가로, 절대 수동으로 검증하고 테스트 코드를 작성하진 않아야 한다. 테스트 코드로 먼저 검증 후, 정말 못 믿겠다는 생각이 들 땐 프로젝트를 실행해 확인한다.
'programming > SpringBoot' 카테고리의 다른 글
[SpringBoot] EC2에 프로젝트 clone 받기 (0) | 2022.03.01 |
---|---|
[SpringBoot] 롬복 (0) | 2021.11.24 |
[SpringBoot] 2장 스프링부트에서 테스트 코드를 작성하자 (0) | 2021.11.11 |
[SpringBoot] 1장 인텔리제이에서 깃과 깃허브 사용하기 (0) | 2021.11.11 |
[SpringBoot] 1장 인텔리제이로 스프링부트 시작하기 (0) | 2021.11.11 |