12.2 주문/목록 CRUD 및 비즈니스 로직 단위 테스트
학습한 지식을 바탕으로 간단한 주문 시스템을 통합하고, 작성한 코드가 올바르게 동작하는지 검증하는 방법을 배웁니다.
1. 요구사항 정의
- 상품을 주문할 수 있다. (기본 재고 확인 로직 포함)
- 주문 목록을 조회할 수 있다.
- 주문을 취소하면 재고가 복구되어야 한다.
2. 도메인 모델 설계 (JPA)
@Entity
@Table(name = "orders")
public class Order {
@Id @GeneratedValue
private Long id;
private String itemName;
private int orderPrice;
private int count;
@Enumerated(EnumType.STRING)
private OrderStatus status; // ORDER, CANCEL
// 생성 메서드, 비즈니스 로직(취소 시 재고 복구) 등을 포함한 도메인 주도 설계
}
3. 단위 테스트 (Unit Test)
Spring Boot 환경에서는 JUnit 5와 Mockito를 사용하여 특정 레이어의 로직만 빠르게 테스트할 수 있습니다.
Service 계층 테스트 예시
@ExtendWith(MockitoExtension.class)
class OrderServiceTest {
@Mock OrderRepository orderRepository;
@InjectMocks OrderService orderService;
@Test
void 주문_성공() {
// given
OrderDto dto = new OrderDto("노트북", 1000, 2);
// when
Long orderId = orderService.createOrder(dto);
// then
verify(orderRepository).save(any(Order.class));
}
}
4. 통합 테스트 (Integration Test)
@SpringBootTest 애너테이션을 사용하여 실제 빈(Bean)들을 컨테이너에 올리고 데이터베이스 연결까지 포함한 테스트를 진행합니다.
@SpringBootTest
@Transactional
class OrderFlowIntegrationTest {
@Autowired OrderService orderService;
@Test
void 전체_주문_흐름_테스트() {
// ... 실제 DB를 사용한 시나리오 테스트
}
}
5. 트랜잭션 관리와 데이터 정합성
실전 미니 프로젝트에서 가장 중요한 부분 중 하나는 트랜잭션 관리 입니다. 여러 엔티티를 조작하는 서비스 메서드에는 반드시 @Transactional을 선언하여 데이터 정합성을 보장해야 합니다.
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
private final ProductRepository productRepository;
@Transactional // 메서드 전체를 하나의 트랜잭션으로 묶음
public Long createOrder(OrderDto dto) {
// 1. 상품 재고 차감 (실패 시 예외 발생)
Product product = productRepository.findByName(dto.getItemName());
product.removeStock(dto.getCount());
// 2. 주문 생성 및 저장
Order order = Order.createOrder(product, dto.getCount());
orderRepository.save(order);
return order.getId();
}
}
- 원자성 보장: 재고는 줄었는데 주문 기록 저장에 실패하는 상황을 방지합니다.
- Dirty Checking: JPA 사용 시 별도의
save()호출 없이도 트랜잭션 종료 시 엔티티의 변경 사항이 DB에 자동 반영됩니다.
🎯 핵심 요점
- 실전 프로젝트에서는 도메인 엔티티 내부에 비즈니스 로직 을 적절히 배치하는 것이 좋습니다.
- 단위 테스트 는 외부 의존성을 제거하고 로직 자체를 빠르게 검증합니다.
- 통합 테스트 는 시스템의 전체적인 흐름이 정상적인지 마지막으로 확인합니다.