도서, 스프링 부트와 AWS로 혼자 구협하는 웹 서비스(2019)를 토대로 공부한 내용입니다.
1. 테스트 코드 관련 개념
1.1. TDD란
- TDD: 테스트가 주도하는 개발
- 즉, 테스트 코드를 먼저 작성하는 것부터 시작
1.1.1. TDD-레드 그린 사이클
- 실패하는 테스트를 먼저 작성한다 (RED)
- 테스트가 통과하는 프로덕션 코드를 작성한다 (GREEN)
- 테스트 통과시 프로덕션 코드를 리팩토링한다 (Refactor)
1.2. 단위 테스트란
- TDD의 첫 단계인 기능단위 테스트 코드 작성
- 테스트 코드를 굳이 먼저 작성하지 않아도 된다
- 리팩토링이 포함되지 않는다
- 테스트 코드만 작성하는 것을 이야기한다
1.2.1. 테스트 코드 작성 이유
- 단위 테스트는 개발단계 초기 문제를 발견하게 도움
- 단위 테스트는 개발자가 나중중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인 가능(ex. 회귀 테스트)
- 단위 테스트는 기능에 대한 불확실성을 감소시킴
- 단위테스트는 시스템에 대한 실제 문서를 제공( 단위 테스트 자체가 문서로 사용)
이런 테스트 코드를 쓰면, system.out.println() 출력으로 눈으로 검증해야하는 불필요한 수동작업을 버릴 수 있다. 다시 정리하면 이렇게 정리된다
1. 빠른 피드백 가능 2. 출력문과 같은 수동검증이 필요없다 3. 개발자가 만든 기능을 안전하게 보호한다 |
3의 경우는 테스트 코드가 기존 기능이 잘 작동됨을 보장해주기 대문에 다른 코드의 추가시의 문제를 조기에 찾을 수 있다.
1.3. 테스트프레임워크
xUnit-JUnit를 써보자.
2. Hello Controller 테스트 코드 작성하기
2.1. 폴더, 패키지, 클래스 생성
- Java > (우클릭)Next → package 생성
- 일반적으로 패키지명은 웹 사이트 주소의 역순 ex) practice.kyu.com → com.kyu.practice
- Java > (우클릭)Next → class 생성
- 이름은 임의로 Application으로 진행
여기까지 했으면 디렉토리가 이렇게 생성된다
2.2. Application 클래스 생성 & 테스트코드 작성
package com.kyu.practice.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.admin.SpringBootApplication;
@SpringBootApplication // 스프링 부트의 자동 설정, 스프링 Bean 읽기와 생성을 모두 자동 설정, 항상 프로젝트 최상단에 위치할 것.
public class Application { //앞으로 진행될 프로젝트의 메인 클래스
public static void main(String [] args){
SpringApplication.run(Appllication.class, args); //내장 was(Web Application Server)실행
}
}
2.2.1. Application 클래스가 하는 일
- 앞으로 만들 프로젝트의 메인 클래스
2.2.2. @springBootApplication
- 이 위치부터 설정을 읽어가므로 항상 프로제트 최사단 위치에 있어야 함
2.2.3. 내장 WAS
- 별도의 외부 WAS없이 애플리케이션 시행시 내부 WAS를 실행함
- 항상 서버에 톰캣을 설치할 필요가 없어진다
- 스프링 부트로 만들어진 Jar파일을 실행하면 된다
- 이를 통해 언제 어디서나 같은 환경의 스프링 부트를 배포할 수 있게 된다
- 많은 회사에서 내장 WAS를 사용/권장 한다
2.3. Web패키지, HelloController생성
2.3.1. Web패키지 역할
- 앞으로 컨트롤러와 관련된 클래스를 담을 패키지
2.3.2. HelloController로 간단한 API작성하기
package 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";
}
}
2.3.3. 테스트 코드를 작성할 클래스 생성
import com.sun.xml.internal.ws.developer.UsesJAXBContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMveTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMve;
import org.springframework.test.web.servlet.ResultActions;
import static org.springframework.test.web.servlet.request.MockMveRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMveResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMveResultMatchers.status;
@RunWith(SpringRunner.class) // 테스트 진행시 jUnit에 내장된 실행자 외의 다른 실행자를 실행시킴
@webMvcTest // 여러 스프링 테스트 어노테이션 중, Web에 집중할 수 있는 어노테이션
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));
}
}
교재와 다른 점
- jupiter5를 사용하기 위해서 책속 교재의 관련 패키지 임폴트문과 어노테이션, 클래스 호출문을 바꿨음.
- 주석 참고
2.3.4. 테스트 코드 실행
- RUN
- 정상실행 확인