티스토리 뷰
반응형
스프링 부트와 테스트 코드
테스트 코드란,
TDD와 단위 테스트는 서로 다른 이야기이다.
- TDD는 테스트가 주도하는 개발. 즉, 테스트 코드를 먼저 작성하는 것을 말한다.
- Red : 항상 실패하는 테스트를 먼저 작성
- Green : 테스트가 통과하는 프로덕션 코드를 작성
- Refactor : 테스트가 통과하면 프로덕션 코드를 리팩토링
- 단위 테스트는 TDD의 첫번째 단계인 기능 단위의 테스트 코드를 작성하는 것을 말한다.
- 단위 테스트는 테스트 코드를 꼭 먼저 작성해야하는 것도 아니고, 리팩토링도 포함되지 않는다. 즉, 순수하게 테스트 코드만 작성하는 것을 말한다.
단위 테스트 코드는 왜 작성하지?
장점을 살펴보자
- 개발단계 초기에 문제를 발견할 수 있다.
- 개발자가 나중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인할 수 있다.(예: 회귀 테스트)
- 기능에 대한 불확실성을 감소시킬 수 있다.
- 단위 테스트 자체를 문서로 사용할 수 있다.
일반적인(?) 테스트는 어떤 식으로 진행되는지 살펴보자
- 개발 요구사항에 맞는 코드를 작성한다.
- 서버(Tomcat)을 실행한다.
- API일 시 API 테스트 도구로 HTTP를 요청한다.
- 요청 결과를 System.out.println()으로 확인한다.
- 예상 못한 결과가 나타날 시 서버를 꺼 소스를 수정한다.
- 테스트 코드를 사용하면 2~5번을 생략하여 빠른 테스트를 진행할 수 있다.
- 테스트 코드를 사용하면 System.out.println으로 확인하지 않고, 자동검증이 가능하다.
- 테스트 코드를 사용하면 개발자가 만든 기능을 안전하게 보호할 수 있다.
- 예를 들어, B라는 기능을 개발 하여 테스트했는데, 기존에 있던 A 기능이 잘 되지 않는다? 이런 문제가 발생하지 않는다.
JUnit 4를 사용하여 테스트 코드를 작성하자
단위 테스트를 작성해보자
@RunWith(SpringRunner.class)
@WebMvcTest
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));
}
}
@RunWith(SpringRunner.class)
- 스프링 부트 테스트와 JUnit 사이에 연결자 역할을 한다.
- 테스트 진행 시 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킨다는 의미로 여기서는 SpringRunner라는 스프링 실행자를 실행시킨다.
@WebMvcTest
- 여러 스프링 테스트 어노테이션 중 Web(Spring MVC)에 집중할 수 있는 어노테이션이다.
- 해당 어노테이션을 선언할 경우 @Controller, @ControllerAdvice를 사용할 수 있다.
- 단, @Service, @Component, @Repository는 사용할 수 없다.
@Autowired
- 스프링(IoC 컨테이너)이 관리하는 Bean을 주입 받는다.
private MovkMvc mvc;
- 웹 API를 테스트할 때 사용한다.
- 스프링 MVC 테스트의 시작점이고, 이 클래스를 통해 HTTP GET, POST 전송 방식에 대한 API 테스트를 진행할 수 있다.
mvc.perform(get("/hello"))
- MockMvc를 통해 /hello 주소로 HTTP GET 요청을 한다.
.andExpect(status().isOk())
- mvc.perform의 결과를 검증한다.
- HTTP Header의 Status를 검증한다.
- 즉, 우리가 흔히 알고 있는 상태코드(200, 404, 500 등)를 검증하는 것이다.
- 여기서 isOk()는 200인지 아닌지를 말하는 것이다.
.andExpect(content().string(hello))
- 응답 본문의 내용을 검증한다.
- HelloController에서는 return 값이 "hello"이므로 검증이 맞다.
실행결과
결과 : 상태코드 200 그리고 리턴 값이 "hello0"라는 것이 정상적으로 검증됐다.
롬복이란,
롬복은 Java 개발 시 자주 사용하는 코드인 Getter, Setter, 기본 생성자, toString 등을 어노테이션으로 자동 생성해주는 것이다.
프로젝트에 롬복을 추가해보자(build.gradle)
compile('org.projectlombok:lombok')
롬복 플러그인을 설치하자
-
윈도우[Ctrl+Shift+A] | 맥[Command+Shift+A]
-
plugins 진입 후 'lombok' 검색
- 'install'을 통해 설치 후 인텔리 제이 재시작한다.
- 재시작할 시 그림과 같이 설정해야할 장소를 알려주는데, 파란색 글씨 클릭
- 진입하여 'Enable annotation processing'을 체크
롬복 활용하기
@Getter
@RequiredArgsConstructor
public class HelloReponseDto {
private final String name;
private final int amount;
}
@Getter
- 선언된 모든 필드의 get 메소드를 생성해준다.
@RequiredArgsConstructor
- final 필드가 포함된 생성자를 생성해준다.
public HelloReponseDto(String name, int amount){}
를 default로 구현한다.
- final이 없는 필드는 생성자에 포함되지 않는다.
테스트 코드를 작성해보자
import static org.assertj.core.api.Assertions.assertThat;
public class HelloReponseDtoTest {
@Test
public void lombokTest() {
String name = "test";
int amount = 1000;
HelloReponseDto dto = new HelloReponseDto(name, amount);
assertThat(dto.getName()).isEqualTo(name);
assertThat(dto.getAmount()).isEqualTo(amount);
}
}
assertThat
- assertj라는 테스트 검증 라이브러리의 검증 메소드이다.
- 검증하고 싶은 대상을 메소드 인자로 받는다.
- 메소드 체이닝이 가능하여 isEqualTo와 같이 메소드를 이어서 사용 가능하다.
- Ex. dto.getName()하고 name이 같니?
isEqualTo
- assertj의 동등 비교 메소드이다.
- assertThat에 있는 값과 isEqualTo의 값을 비교해서 같을 때만 성공이다.
JUnit의 assertThat과 assertj의 asserThat
- JUnit의 assertThat을 사용하게 되면 is()와 같은 CoreMatchers 라이브러리가 필요하는 반면, assertj의 assertThat을 사용하면 필요없다.
- assertj의 assertThat을 사용하면 자동완성이 확실하게 지원된다.
HelloController에 DTO추가 후 테스트 진행해보자
//HelloController
@GetMapping("/hello/dto")
public HelloReponseDto helloDto(@RequestParam("name") String name, @RequestParam("amount") int amount) {
return new HelloReponseDto(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)));
}
param
- API 테스트할 시 사용될 요청 파라미터를 설정한다.
- 단, 값은 String 값만 사용 가능하다.
- 그래서 숫자/날짜 등의 데이터를 등록할 시에도 String값으로 변환해야 한다.
jsonPath
- JSON 응답값을 필드별로 검증할 수 있는 메소드이다.
- $를 기준으로 필드명을 명시한다.
- Controller에서 return값을 dto의 생성자로 했는데, dto에서 생성자와 get을 어노테이션을 통해 설정해놓았으므로 get을 통해 값들을 확인할 수 있는 것이다.(JSON 형태는 @RestController 때문에 가능)
참고
http://www.yes24.com/Product/Goods/83849117?Acode=101
반응형
'Spring > SpringBoot 실습' 카테고리의 다른 글
[SpringBoot 실습] JPA로 데이터베이스를 다뤄보자 (2) | 2020.01.25 |
---|---|
[SpringBoot 실습] 실습 요구사항 (0) | 2020.01.25 |
[SpringBoot 실습] 스프링 부트의 기본 애노테이션 (0) | 2020.01.20 |
[SpringBoot 실습] gradle 기반 Spring boot 프로젝트 생성 (0) | 2020.01.20 |
[SpringBoot 실습] 시작에 앞서.. (0) | 2020.01.20 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 스프링부트
- 자바8
- mustache
- effectivejava
- 이펙티브 자바
- java
- 연관관계
- jdk버전
- ifPresent
- try catch finally
- 빈 순환 참조
- 빌더 패턴
- 생성자
- 복사 팩토리
- springboot
- 정적팩터리메서드
- 김영한
- java8
- 인프런
- try with resources
- flatMap
- Spring
- JPA
- package-private
- 점층적 생성 패턴
- junit
- 팩토리 메소드 패턴
- @Lazy
- 이펙티브자바
- Effective Java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함