[Day-10] 주문기능테스트, 부트스트랩적용WEB JAVA SPRING/PROJECT2023. 8. 25. 16:11
Table of Contents
#주문기능테스트
테스트 요구사항
- 상품 주문이 성공해야 한다.
- 상품을 주문할 때 재고 수량을 초과하면 안 된다.
- 주문 취소가 성공해야 한다.
OrderServiceTest
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class OrderServiceTest {
@Autowired
EntityManager em;
@Autowired
OrderService orderService; //OrderService 받아옴
@Autowired
OrderRepository orderRepository;
@Test
public void 상품주문() throws Exception {
//given
Member member = createMember();
Book book = createBook("시골 JPA", 10000, 10); //이름, 가격, 재고
int orderCount = 2;
//when
Long orderId = orderService.order(member.getId(), book.getId(), orderCount);
//then
Order getOrder = orderRepository.findOne(orderId);
//assertEquals(x, y,z) 객체 x와 y가 일치함을 확인 z :실제값
assertEquals("상품 주문시 상태는 ORDER", OrderStatus.ORDER, getOrder.getStatus());
assertEquals("주문한 상품 종류 수가 정확해야 한다.", 1, getOrder.getOrderItems().size());
assertEquals("주문 가격은 가격 * 수량이다.",10000 * orderCount,getOrder.getTotalPrice());
assertEquals("주문 수량만큼 재고가 줄어야 한다.",8, book.getStockQuantity());
}
@Test(expected = NotEnoughStockException.class) //재고수량 초과되면 예외가 터져야함
public void 상품주문_재고수량초과() throws Exception {
//given
Member member= createMember();
Item item = createBook("시골",10000,10); //재고 10개인데
int orderCount =11; //11개 주문하면
//when
Long orderId = orderService.order(member.getId(), item.getId(), orderCount); //잘못된거니까 예외터져야
//then
fail("재고 수량 부족 예외가 발생해야 하는데 여기로 오면 잘못된 코드다");
}
@Test
public void 주문취소() throws Exception {
//given : 이런게 주어짐
Member member= createMember();
Book item = createBook("시골",10000,10); //10개에서
int orderCount =2; //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 Book createBook(String name, int Price, int stockQuantity) {
Book book = new Book();
book.setName(name);
book.setPrice(Price);
book.setStockQuantity(stockQuantity); //ctrl alt p
em.persist(book);
return book;
}
private Member createMember() {
Member member = new Member();
member.setName("회원1");
member.setAddress(new Address("서울", "강가", "123"));
em.persist(member);
return member;
}
}
OrderRepository
@Repository
@RequiredArgsConstructor
public class OrderRepository {
private final EntityManager em;
public void save(Order order) {
em.persist(order);
}
//단건 조회
public Order findOne(Long id) {
return em.find(Order.class, id);
}
동적쿼리 jpql로 작성시 오류발생확률 높고... 실무에서 안씀!!
//주문내역 검색
public List<Order> findAll(OrderSearch orderSearch) {
String jpql = "select o from Order o join o.member m"; //order를 조회하고 order랑 order랑 연관된 member를 join한다.
boolean isFirstCondition = true;
//주문 상태 검색
if (orderSearch.getOrderStatus() != null) { //값이 있으면
if (isFirstCondition) {
jpql += " where";
isFirstCondition = false;
} else {
jpql += " and";
}
jpql += " o.status = :status";
}
//회원 이름 검색
if (StringUtils.hasText(orderSearch.getMemberName())) {
if (isFirstCondition) {
jpql += " where";
isFirstCondition = false;
} else {
jpql += " and";
}
jpql += " m.name like :name";
}
TypedQuery<Order> query = em.createQuery(jpql, Order.class).setMaxResults(1000); //최대 1000건
if (orderSearch.getOrderStatus() != null) {
query = query.setParameter("status", orderSearch.getOrderStatus());
}
if (StringUtils.hasText(orderSearch.getMemberName())) {
query = query.setParameter("name", orderSearch.getMemberName());
}
return query.getResultList();
}
}
JPA가 제공하는 표준 동적쿼리 (JPA Criteria) : 유지보수성 제로, 실무에서 안씀
public List<Order> findAllByCriteria(OrderSearch orderSearch) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> o = cq.from(Order.class);
Join<Order, Member> m = o.join("member", JoinType.INNER); //회원과 조인
List<Predicate> criteria = new ArrayList<>();
//주문 상태 검색
if (orderSearch.getOrderStatus() != null) {
Predicate status = cb.equal(o.get("status"),
orderSearch.getOrderStatus());
criteria.add(status);
}
//회원 이름 검색
if (StringUtils.hasText(orderSearch.getMemberName())) {
Predicate name =
cb.like(m.<String>get("name"), "%" +
orderSearch.getMemberName() + "%");
criteria.add(name);
}
cq.where(cb.and(criteria.toArray(new Predicate[criteria.size()])));
TypedQuery<Order> query = em.createQuery(cq).setMaxResults(1000); //최대 1000 건
return query.getResultList();
}
-> Querydsl 사용할 것
<웹 계층 개발>
HomeController
@Controller
@Slf4j //logger(lombok)
public class HomeController {
@RequestMapping("/")
public String home(){
log.info("home controller");
return "home"; //home.html 찾아간다.
}
}
#Thymeleaf layout
https://www.thymeleaf.org/doc/articles/layouts.html
#부트스트랩 적용
다운
home.html 일부
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments/header :: header"> <!--include header 느낌
fragments/header의 위치에 header 라는 파일이 있다 -->
header.html 일부
<head th:fragment="header"><!--이거를 home으로-->
'WEB JAVA SPRING > PROJECT' 카테고리의 다른 글
[Day-12] 상품 등록, 목록, 수정 (0) | 2023.08.25 |
---|---|
[Day-11] 회원 등록, 목록 조회 (0) | 2023.08.25 |
[Day-9] 주문 엔티티, 리파지토리, 서비스 (0) | 2023.08.25 |
[Day-8] 상품 엔티티, 리파지토리, 서비스 (0) | 2023.08.25 |
[Day-7] 회원 도메인, 리포지토리, 서비스, 회원 기능 테스트 (0) | 2023.08.25 |