본문 바로가기
[inflearn] 스프링 핵심 원리 - 기본편/섹션 2 - 예제 만들기

11. 주문과 할인 도메인 테스트

by 슬픈 야옹이 2023. 10. 6.

지난 포스트에서 개발한 주문과 할인 도메인의 테스트를 진행한다.

https://debuggingworld.tistory.com/88

 

10. 주문과 할인 도메인 개발

지난 포스트에서 설계한 주문과 할인 도메인을 바탕으로 개발을 진행한다. https://debuggingworld.tistory.com/87 9. 주문과 할인 도메인 설계 이어서 비즈니스 요구사항에 따라 주문과 할인 도메인을 설

debuggingworld.tistory.com

 

역시 main 메서드에서 실행하는 방법과 테스트 프레임워크(JUnit)을 활용하는 방법 두가지로 진행한다.

 

 

main 메서드에서 실행하는 방법

core 패키지 하위에 OrderApp 클래스를 생성한다.

OrderApp 클래스 생성

 

OrderApp.java

 

OrderApp.java

package hdxian.hdxianspringcore;

import hdxian.hdxianspringcore.member.Grade;
import hdxian.hdxianspringcore.member.Member;
import hdxian.hdxianspringcore.member.MemberService;
import hdxian.hdxianspringcore.member.MemberServiceImpl;
import hdxian.hdxianspringcore.order.Order;
import hdxian.hdxianspringcore.order.OrderService;
import hdxian.hdxianspringcore.order.OrderServiceImpl;

public class OrderApp {

    public static void main(String[] args) {
        MemberService memberService = new MemberServiceImpl();
        OrderService orderService = new OrderServiceImpl();

        Long memberId = 1L;
        Member member = new Member(memberId, "memberA", Grade.VIP);
        memberService.join(member);

        Order order = orderService.createOrder(1L, "itemA", 10000);

        System.out.println("order = " + order);
        System.out.println("order.calculatePrice = " + order.calculatePrice());

    }

}

 

main 메서드에서 memberService를 통해 id가 1, 이름은 memberA, 등급은 VIP인 회원을 가입시키고,

memberA의 회원id(1)로 주문을 생성한 뒤, 결과를 출력해 확인한다.

 

VIP등급의 회원이 가격이 10000원인 물건을 주문했으니 1000원이 할인되어 calculatePrice()의 결과로 9000원이 나와야 한다.

테스트 결과 (성공 시)

 

 

 

 

테스트 프레임워크(JUnit)를 활용하는 방법

test 폴더 하위에 order 패키지를 생성한 뒤, OrderServiceTest 클래스를 생성한다.

 

OrderServiceTest 클래스 생성

 

OrderServiceTest.java

 

OrderServiceTest.java

package hdxian.hdxianspringcore.order;

import hdxian.hdxianspringcore.member.Grade;
import hdxian.hdxianspringcore.member.Member;
import hdxian.hdxianspringcore.member.MemberService;
import hdxian.hdxianspringcore.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class OrderServiceTest {

    MemberService memberService = new MemberServiceImpl();
    OrderService orderService = new OrderServiceImpl();


    @Test
    void createOrder() {
        // given
        // 원시 타입에는 null을 넣을 수 없어서 Long 타입을 씀.
        Long memberId = 1L;
        Member member = new Member(memberId, "memberA", Grade.VIP);
        memberService.join(member);

        // when
        Order order = orderService.createOrder(memberId, "itemName", 10000);

        // then
        // 할인액이 1000원이 맞는지 테스트
        Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000);

    }

}

 

id가 1, 이름은 memberA, 등급은 VIP인 회원을 가입시킨 뒤 (given)

 

10000원짜리 상품을 주문하면 (when)

 

할인 액수가 1000원이 맞는지 테스트한다. (then)

 

테스트 결과 (성공 시)

 

isEqualTo()에 4000을 전달해 테스트를 실패시켜 보았다.

테스트 결과 (실패 시)

 

 

+) 아래와 같이 패키지 단위로 테스트를 진행할 수도 있다.

패키지 단위로 테스트

 

 

단위 테스트 설계

강의에서 한 가지 강조한 점은, 테스트 코드를 작성할 때 단위 테스트를 잘 설계해야 한다는 것이었다.

 

프로젝트 규모가 커지면 각종 스프링 컨테이너, DB 등등 연동 시스템이 많아지는데, 그럴수록 통합 테스트는 테스트 한번 한번에 많은 시간이 걸린다.

 

그에 반해 단위 테스트는 자바 코드만 독립적으로 실행되기 때문에 테스트 속도가 빠르다.

 

따라서 효율적인 테스트를 위해서는 지금 작성한 테스트와 같은 단위 테스트를 잘 설계하는 것이 중요하다.

 

+)

단위 테스트는 프로그램의 하위 구성 요소 각각에 대한 테스트라면, 통합 테스트는 그러한 요소들의 연계에 대한 테스트다.

 

스프링에서 @SpringBootTest 어노테이션이 붙은 테스트 클래스는 테스트 진행 시 스프링 컨테이너 등 연계 시스템을 모두 띄워서 테스트를 진행한다.

실제 어플리케이션의 동작을 테스트해볼 수 있지만, 테스트하는데 시간이 오래걸린다. 일종의 통합 테스트를 진행한다고 볼 수 있다.

@SpringBootTest

 

그에 반에 @Test가 붙은 메서드는 단순히 해당 메서드의 자바 코드를 동작시킨다.

일종의 단위 테스트라고 볼 수 있다.

@Test

 

 

 

이로써 비즈니스 요구사항에 대한 모든 구현이 완료되었다. 프로그램이 완성된 것이다.

 

이 프로젝트는 스프링 기능 없이 순수 자바 코드로 객체 지향 프로그래밍을 진행해보고, 그에 따라 발생하는 문제점이나 고려해야 할 점 등을 알아보는 것에 그 목적이 있다.

 

다음 강의, 혹은 다음 포스트부터는 비즈니스 요구사항이 변경되는 시나리오 속에서

이 어플리케이션에서 정말 객체 지향 원칙이 잘 지켜졌는지 등을 살펴본다,