애플리케이션 모듈 독립적 테스트
비용이 적게 들어 피드백하기 쉽다
애플리케이션을 구헝하는 모듈을 결합해 전체적인 로직이 의도한 대로 동작하는 지 테스트
테스트 비용 커짐
Given - 테스트에 필요환 환경 설정
When - 실제 테스트 코드 포함, 결과 가져옴
Then - 결과 검증
Fast
빠르게
Isolated
목적 대상에 대해서만
Repeatable
반복 가능하게
Self-Validating
테스트의 성공 실패 유무도 검증할 수 있어야함
Timely
애플리케이션 코드 구현 전에 완성
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private final Logger LOGGER = (Logger) LoggerFactory.getLogger(ProductServiceImpl.class);
@Override // 읽기 메소드
public ProductResponseDto getProduct(Long number) {
LOGGER.info("[getProduct] input number : {}",number);
Product product = productRepository.findById(number).get();
LOGGER.info("[getProduct] product number : {}, name : {}", product.getNumber(),product.getName());
ProductResponseDto productResponseDto = new ProductResponseDto();
productResponseDto.setNumber(product.getNumber());
productResponseDto.setName(product.getName());
productResponseDto.setPrice(product.getPrice());
productResponseDto.setStock(product.getStock());
return productResponseDto;
}
@Test
테스트 코드 포함 메소드 정의
@BeforeAll
테스트 시작 전 호출 메서드 정의
@BeforeEach
각 테스트 메서드가 실행 전 동작하는 메서드
@AfterAll
테스트 종료 후 호출 메서드 정의
@AfterEach
각 테스트 종료 후 호출되는 메서드 정의
하나의 모듈만 테스트하고자 할 때 외부에서 주입받는 객체는 외부 요인에 해당한다.
외부 요인의 관여 없이 테스트해야 하기 때문에 Mock 객체를 생성해서 해결한다.
@WebMvcTest
웹에서 사용되는 요청과 응답 테스트 수행
대상 클래스만 로드해 테스트를 수행한다.
@MockBean
가짜 객체를 생성해 주입하는 역할로 Mockito의 given() 메소드를 통해 동작을 정의해야한다
@Test
테스트 코드가 포함됐다고 선언하는 어노테이션 JUnit Jupiter에서 해당 어노테이션을 감지해 테스트 계획에 추가한다.
@DisplayName
테스트 메소드 이름이 복잡해 가독성이 떨어질 경우 테스트 표현 정의를 보기 쉽게 정의할 수 있다.
@WebMvcTest
어노테이션을 사용한 테스트를 슬라이스 테스트라고 하며 단위 / 통합 테스트의 중간 개념이다.@WebMvcTest(ProductController.class)
public class ProductController {
@Autowired
private MockMvc mockMvc;
@MockBean
ProductServiceImpl productService;
@Test
@DisplayName("MockMvc를 통한 Product 데이터 가져오기 테스트")
void getProductTest() throws Exception{
given(productService.getProduct(123L)).willReturn(
new ProductResponseDto(123L,"pen", 5000,2000)
);
String productId="123";
mockMvc.perform(
get("/product?numebr="+productId)
).andExpect(status().isOk())
.andExpect(jsonPath("$.number").exists())
.andExpect(jsonPath("$.name").exists())
.andExpect(jsonPath("$.price").exists())
.andExpect(jsonPath("$.stock").exists())
.andDo((print()));
verify(productService).getProduct(123L);
}
}
given()
어떤 메소드가 호출 되어 어떤 파라미터 주입 받는 지 가정
willReturn()
어떤 결과를 리턴할 것인지 정의한다.
MockMvc
서블릿 컨테이너 없이 가상의 MVC 환경에서 모의 HTTP 서블릿 요청하는 유틸리티 클래스
perform()
서버로 URL 요청을 보내는 것처럼 테스트 코드를 작성하고 HTTP 요청 정보를 설정해 테스트할 수 있다.
andExpect()
사용해 결괏값 검증 ResultMatcher 활용 생성
jsonPath().exists()
해당 값이 존재하는 지 검증
andDo()
요청 응답 전체 내용 확인
verify
메서드가 실행됐는 지 검증하는 역할로 given()
에 정의된 동작과 대응