
예외 활용
- 스프링 기본적으로 체크 예외는 비즈니스 의미가 있을 때 사용하고, 런타임(언체크) 예외는 복구 불가능한 예외로 가정한다.
- 체크 예외 : 비즈니스 의미가 있을 때 사용
- 언체크 예외 : 복구 불가능한 예외
- 체크 예외를 할용하여 비즈니스 예외를 해결
예)
public class NotEnoughMoneyException extends Exception{
public NotEnoughMoneyException(String message) {
super(message);
}
}
@Entity
@Table(name = "orders")
@Getter
@Setter
public class Order {
@Id
@GeneratedValue
private Long id;
private String username;
private String payStatus;
}
public interface OrderRepository extends JpaRepository<Order, Long> {
}
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository repository;
@Transactional
public void order(Order order) throws NotEnoughMoneyException {
log.info("order 호출");
repository.save(order);
log.info("결제 프로세스 진입");
if(order.getUsername().equals("예외")) {
log.info("시스템 예외 발생");
throw new RuntimeException("시스템 예외");
} else if(order.getUsername().equals("잔고부족")) {
log.info("잔고 부족 비즈니스 예외 발생");
order.setPayStatus("대기");
throw new NotEnoughMoneyException("잔고가 부족합니다");
} else {
log.info("정상 승인");
order.setPayStatus("완료");
}
log.info("결제 프로세스 완료");
}
}
@Slf4j
@SpringBootTest
class OrderServiceTest {
@Autowired
OrderService orderService;
@Autowired
OrderRepository orderRepository;
@Test
void complete() throws NotEnoughMoneyException {
Order order = new Order();
order.setUsername("정상");
orderService.order(order);
Order findOrder = orderRepository.findById(order.getId()).get();
Assertions.assertThat(findOrder.getPayStatus()).isEqualTo("완료");
}
@Test
void runtimeException() {
Order order = new Order();
order.setUsername("예외");
Assertions.assertThatThrownBy(() -> orderService.order(order))
.isInstanceOf(RuntimeException.class);
Optional<Order> orderOptional = orderRepository.findById(order.getId());
Assertions.assertThat(orderOptional.isEmpty()).isTrue();
}
@Test
void bizException() {
Order order = new Order();
order.setUsername("잔고부족");
try {
orderService.order(order);
} catch (NotEnoughMoneyException e) {
log.info("고객에게 잔고 부족 알림 별도의 계좌로 입금 안내");
}
Order findOrder = orderRepository.findById(order.getId()).get();
Assertions.assertThat(findOrder.getPayStatus()).isEqualTo("대기");
}
}