* 테스트 코드에 대해 공부해보기
TDD란?
- 테스트가 주도하는 개발
- 테스트 코드먼저 작성하는 것 부터 시작
1. 항상 실패하는 테스트를 먼저 작성하고(RED)
2. 테스트가 통과하는 프로덕션 코드를 작성하고(GREEN)
3. 테스트가 통과하면 프로덕션 코드를 리팩토링합니다.(REFACTOR)
단위테스트란?
- TDD의 첫번째 단계인 기능단위의 테스트 코드를 작성하는것을 말함
테스트코드의 작성이유?
- 초기에 문제 발견하도록 도와줌
- 기능에 대한 불확실성을 감소시킬 수 있음
- 단위테스트는 시스템에 대한 실제문서를 제공함(단위테스트 자체가 문서로 사용가능)
- 나중에 코드를 리팩토링하거나 라이브러리 업그레이드 등에서 기존 기능이 올바르게 작동하는지 확인 가능
기존 기능이 잘 작동되는것을 보장해주는것이 테스트 코드 **
가장 대중적인 테스트 프레임워크 : xUnit
- JUnit : Java
- DBUnit : DB
우리는 자바용인 Jnit 사용해볼것.
이제 실습 시작.
1. 프로젝트 생성
2. Application 클래스 생성
- 프로젝트의 main 클래스
- @SpringBootApplication으로 인해 스프링 부트의 자동설정, 스프링 Bean읽기와 생성을 모두 자동으로 설정.
- @SpringBootApplication이 있는 위치부터 설정을 읽음 => 프로젝트의 최상단에 위치해야만함
- SpringAppliction.run으로 내장 was 실행
* @RestController
- 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어줌
- 예전에는 @ResponseBody를 각 메소드마다 선언했던 것을 한번에 사용할 수 있게끔
* @GetMapping
- HTTPMethod인 Get의 요청을 받을 수 있는 Api를 만들어줌(받는 url 설정)
- 예전에는 @RequestMapping(method=RequestMethod.GET)으로 사용되었음
3. test코드 작성
* @RunWith(SpringRunner.class)
- 테스트를 진행할때 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킴
- 스프링부트 테스트와 JUnit 사이에 연결자 역할을 함
- 괄호안에 들어가있는 SpringRunner.class를 같이 실행
* @WebMvcTest
- Web(Spring MVC)에 집중할 수 있는 어노테이션
- 선언할 경우@Controller, @ControllerAdvice 등을 사용할 수 있음
- @Service, @Component, @Repository 등은 사용할 수 음
- 여기서는 컨트롤러만 사용하기 때문에 선언
* @Autowired
- 스프링이 관리하는 빈(Bean)을 주입받음
* private MockMvc mvc
- 웹 API를 테스트를 할 때 사용
- 스프링 MVC 테스트의 시작점
- 이 클래스를 통해 HTTP GET, POST 등에 대한 API 테스트를 할 수 있음
* mvc.perform(get("/hello"))
- MockMvc를 통해 /hello 주소로 HTTP GET요청을 함
- 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언할 수 있음
* .andExpect(status().isOk())
- mvc.perform의 결과를 검증
- HTTP Header의 Status를 검증
* .andExpect(content().string(hello))
- mvc.perform의 결과를 검증
- 응답 본문의 내용을 검증
중간에 오류가 발생했는데 한글로 클래스명해서 나는 에러인듯
Execution failed for task ':test'.
No tests found for given includes :
이런 에러가 발생하면 settings > Build, Execution, Deployment > Gradle
IntelliJ IDEA로 값을 바꿔주면된다.
롬복이란?
Lombok은 @어노테이션을 제공하고
이를 기반으로 반복 소스코드를 컴파일 과정에서 생성해주는 방식으로 동작하는 라이브러리
롬복 추가
- 롬복은 프로젝트마다 설정해야함
- 플러그인은 한번만 설치하면되지만 build.gradle에 라이브러리를 추가하는 것과 enable시키는 것은 프로젝트마다 설정
롬복으로 기존 소스 리팩토링
package com.springboot_book.first.web.dto;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public class HelloResponseDto {
private final String name;
private final int amount;
}
* @Getter
- 선언된 모든 필드의 get 메소드를 생성해줌
* @RequiredArgsConstructor
- 선언된 모든 final 필드가 포함된 생성자를 생성해줌
- final이 없는 필드는 생성자에 포함되지 않는다.
package com.springboot_book.first.web.dto;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class HelloResponseDtoTest {
@Test
public void 롬복_기능_테스트(){
//given
String name = "test";
int amount =1000;
//when
HelloResponseDto dto = new HelloResponseDto(name,amount);
//then
assertThat(dto.getName()).isEqualTo(name);
assertThat(dto.getAmount()).isEqualTo(amount);
}
}
* assertThat
- assertj라는 테스트 검증 라이브러리의 검증 메소드
- 검증하고 싶은 대상을 메소드 인자로 받음
- 메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이어서 사용가능
* isEqualTo
- assertj의 동등 비교 메소드
- assertThat에 있는 값과 isEqualTo의 값을 비교해서 같을때만 성공
*** Junit의 기본 assertThat이 아닌 assertj의 assertThat을 사용한 이유
- CoreMathers와 달리 추가적으로 라이브러리가 필요하지않음
- 자동완성이 좀 더 확실하게 지원됨
* @RequestParam
- 외부에서 API로 넘긴 파라미터를 가져옴
- 외부에서 넘긴 파라미터를 메소드 파라미터에 저장하게 됨
@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만 허용되므로 숫자, 날짜모양의 데이터를 등록할때 문자열로 변경해야만 가능
* jsonPath
- JSON 응답값을 필드별로 검증할 수 있는 메소드
- $를 기준으로 필드명을 명시
'개발공부 > 웹개발' 카테고리의 다른 글
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 (~100p) (0) | 2022.05.01 |
---|---|
메세지큐란? (Message Queue) (0) | 2022.04.28 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 (~49p) (0) | 2022.03.18 |
스프링 부트와 AWS로 혼자 구현하는 웹 서비스 (~39p) (0) | 2022.03.13 |
[JSTL] GET, POST로 받은 파라미터 바로 사용하기 (0) | 2021.04.28 |