Practical Testing: 실용적인 테스트 가이드 강의 | 박우빈 - 인프런
미션: Layered Architecture 레이어별로 어떤 특징이 있고, 어떻게 테스트를 하면 좋을지 작성
Presentation Layer
외부 세계의 요청을 가장 먼저 받는 계층
파라미터에 대한 최소한의 검증을 수행
테스트 방법:
Mock 객체를 활용하여 하위 레이어와의 상호작용 검증
@WebMvcTest(controllers = ProductController.class)
class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean
private ProductService productService;
@Test
void getSellingProducts() throws Exception {
// given
List<ProductResponse> result = List.of();
when(productService.getSellingProducts()).thenReturn(result);
// when // then
mockMvc.perform(
get("/api/v1/products/selling")
)
.andDo(print())
.andExpect(status().isOk())
;
}
검증 로직 확인
@Test
void createProductWithoutprice() throws Exception {
// given
ProductCreateRequest request = ProductCreateRequest.builder()
.name("아메리카노")
.build();
// when // then
mockMvc.perform(
post("/api/v1/products/new")
.content(objectMapper.writeValueAsString(request))
.contentType(MediaType.APPLICATION_JSON)
)
.andExpect(jsonPath("$.message").value("상품 판매상태는 필수입니다."))
;
}
Business Layer
비즈니스 로직을 구현하는 역할
Persistence Layer와의 상호작용(Data를 읽고 쓰는 행위)를 통해 비즈니스 로직을 전개
트랜잭션을 보장
테스트 방법:
@Test
void createOrder() {
// given
LocalDateTime registeredDateTime = LocalDateTime.now();
Product product = createProduct(HANDMADE, "001", 1000);
productRepository.saveAll(List.of(product));
OrderCreateRequest request = OrderCreateRequest.builder()
.productNumbers(List.of("001"))
.build();
// when
OrderResponse orderResponse = orderService.creatOrder(
request.toServiceRequest(),
registeredDateTime);
// then
assertThat(orderResponse.getProducts()).hasSize(1)
.extracting("productNumber", "price")
.containsExactlyInAnyOrder(
tuple("001", 1000)
);
}
assertThatThrownBy(() -> orderService.creatOrder(request.toServiceRequest(),
registeredDateTime))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("재고가 부족한 상품이 있습니다.");
@AfterEach
void tearDown() {
productRepository.deleteAllInBatch();
}
Persistence Layer
Data Access의 역할
비즈니스 가공 로직이 포함되어서는 안됨
Data에 대한 CRUD에만 집중한 레이어
QueryDSL이나 별도의 DAO를 사용하다가 비즈니스 로직이 침투하는 경우 유의
테스트 방법:
@Test
void findAllBySellingStatusIn() {
// given
Product product = createProduct("001", HANDMADE, HOLD, "카페라떼", 4500);
productRepository.saveAll(List.of(product));
// when
List<Product> products =
productRepository.findAllBySellingStatusIn(List.of(HOLD));
// then
assertThat(products).hasSize(1);
}