06 주문 도메인 개발- Order 기능 테스트

shin·2023년 10월 9일
0

💡 테스트 요구사항

  • 상품 주문이 성공해야 함
  • 상품을 주문할 때 재고 수량을 초과하면 안됨
  • 주문 취소가 성공해야 함

1. Order Test Code

1) 전체 테스트 코드

package jpabook.jpashop.service;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jpabook.jpashop.domain.*;
import jpabook.jpashop.domain.item.Book;
import jpabook.jpashop.exception.NotEnoughStockException;
import jpabook.jpashop.repository.OrderRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class OrderServiceTest {

    @PersistenceContext EntityManager em;

    @Autowired OrderService orderService;
    @Autowired OrderRepository orderRepository;

    @Test
    public void 상품주문() throws Exception {
        //given
        Member member = createMember();
        Item item = createBook("쉽게 배우는 JPA", 10000, 10);

        int orderCount = 2;

        //when
        Long orderId = orderService.order(member.getId(), item.getId(), orderCount);

        //then
        Order getOrder = orderRepository.findOne(orderId);

        assertEquals("상품 주문시 상태는 ORDER", OrderStatus.ORDER, getOrder.getStatus());
        assertEquals("주문한 상품 종류 수가 정확해야 한다", 1, getOrder.getOrderItems().size());
        assertEquals("주문 가격은 가격 * 수량이다", 10000 * 2, getOrder.getTotalPrice());
        assertEquals("주문 수량만큼 재고가 줄어야 한다", 8, item.getStockQuantity());
    }

    @Test(expected = NotEnoughStockException.class)
    public void 상품주문_재고수량초과() throws Exception {
        //given
        Member member = createMember();
        Item item = createBook("쉽게 배우는 JPA", 10000, 10);

        int orderCount = 11;

        //when
        orderService.order(member.getId(), item.getId(), orderCount);

        //then
        fail("재고 수량 부족 예외가 발생해야 한다.");
    }

    @Test
    public void 주문취소() throws Exception {
        //given
        Member member = createMember();
        Item item = createBook("쉽게 배우는 JPA", 10000, 10);

        int orderCount = 2;

        Long orderId = orderService.order(member.getId(), item.getId(), orderCount);
        
        //when
        orderService.cancelOrder(orderId);
        
        //then
        Order getOrder = orderRepository.findOne(orderId);

        assertEquals("주문 취소시 상태는 CANCEL 이다.", OrderStatus.CANCEL, getOrder.getStatus());
        assertEquals("주문이 취소된 상품은 그만큼 재고가 증가해야 한다.", 10, item.getStockQuantity());
    }

    private Member createMember() {
        Member member = new Member();
        member.setName("memberA");
        member.setAddress(new Address("서울", "강가", "123-456"));
        em.persist(member);
        return member;
    }

    private Book createBook(String name, int price, int stockQuantity) {
        Book book = new Book();
        book.setName(name);
        book.setPrice(price);
        book.setStockQuantity(stockQuantity);
        em.persist(book);
        return book;
    }
    
}
  • 모든 테스트 수행 완료


1) 상품 주문 테스트

    @Test
    public void 상품주문() throws Exception {
        //given
        Member member = createMember();
        Item item = createBook("쉽게 배우는 JPA", 10000, 10);

        int orderCount = 2;

        //when
        Long orderId = orderService.order(member.getId(), item.getId(), orderCount);

        //then
        Order getOrder = orderRepository.findOne(orderId);

        assertEquals("상품 주문시 상태는 ORDER", OrderStatus.ORDER, getOrder.getStatus());
        assertEquals("주문한 상품 종류 수가 정확해야 한다", 1, getOrder.getOrderItems().size());
        assertEquals("주문 가격은 가격 * 수량이다", 10000 * 2, getOrder.getTotalPrice());
        assertEquals("주문 수량만큼 재고가 줄어야 한다", 8, item.getStockQuantity());
    }
    private Member createMember() {
        Member member = new Member();
        member.setName("memberA");
        member.setAddress(new Address("서울", "강가", "123-456"));
        em.persist(member);
        return member;
    }

    private Book createBook(String name, int price, int stockQuantity) {
        Book book = new Book();
        book.setName(name);
        book.setPrice(price);
        book.setStockQuantity(stockQuantity);
        em.persist(book);
        return book;
    }
  • 상품 주문이 정상 동작하는지 확인하는 테스트\
  • Given : 테스트를 위한 회원과 상품 생성
  • When : 상품 주문
  • Then : 주문 상태가 ORDER인지, 주문한 상품 종류 수가 정확한지, 주문 가격이 올바른지, 주문 후 재고 수량이 정확히 줄어들었는지 assertEquals를 사용하여 검증 수행
  • assertEquals(message, Object expected, Object.actual)

  • 위 코드로 테스트 수행 시 테스트가 성공으로 종료됨

  • 만약 임의로 틀린 값으로 변경해서 테스트를 실행해보면 X로 종료가 됨



2) 상품주문 재고수량 초과 테스트

    @Test(expected = NotEnoughStockException.class)
    public void 상품주문_재고수량초과() throws Exception {
        //given
        Member member = createMember();
        Item item = createBook("쉽게 배우는 JPA", 10000, 10);

        int orderCount = 11;

        //when
        orderService.order(member.getId(), item.getId(), orderCount);

        //then
        fail("재고 수량 부족 예외가 발생해야 한다.");
    }
  • 재고 수량을 초과해서 상품을 주문하도록 하여, NotEnoughStockException 예외가 발생하는지 검증하는 테스트 수행
  • 위 코드를 보면 재고는 10권인데 orderCount는 11로 재고보다 1권 더 많은 수량을 주문하도록 로직을 작성함
  • Given : 테스트를 위한 회원과 상품 생성 및 주문 수량 세팅
  • When : 상품 주문
  • Then : 예외가 발생하지 않았을 경우 fail 문구 출력
  • 테스트 수행 시 주문 초과가 발생하여 예외가 발생했기 때문에, 아래와 같이 성공으로 테스트가 종료가 됨

  • 만약 위 코드를 수정하여 재고 10권에 딱 맞춰서 orderCount를 10으로 설정하여 주문 테스트를 수행하면, 예외가 발생하지 않았기 때문에 x로 테스트가 종료가 됨



3) 주문 취소 테스트

    @Test
    public void 주문취소() throws Exception {
        //given
        Member member = createMember();
        Item item = createBook("쉽게 배우는 JPA", 10000, 10);

        int orderCount = 2;

        Long orderId = orderService.order(member.getId(), item.getId(), orderCount);
        
        //when
        orderService.cancelOrder(orderId);
        
        //then
        Order getOrder = orderRepository.findOne(orderId);

        assertEquals("주문 취소시 상태는 CANCEL 이다.", OrderStatus.CANCEL, getOrder.getStatus());
        assertEquals("주문이 취소된 상품은 그만큼 재고가 증가해야 한다.", 10, item.getStockQuantity());
    }
  • 주문이 취소되면 그만큼 재고가 증가하는지 확인하는 테스트
  • 주문을 취소하기 위해 먼저 주문을 수행하는 로직을 작성해야 함
  • Given : 상품 주문
  • When : 주문 취소
  • Then : 주문상태가 주문 취소 상태(CANCEL)인지, 취소한 만큼 재고가 증가했는지 검증
  • 주문 취소 테스트 수행 시 정상 테스트 종료


강의 : 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

profile
Backend development

0개의 댓글