W4D1- SpringBootPart2

Onni·2021년 8월 29일
0

TIL

목록 보기
6/21

소프트웨어 테스팅

목적 : 지속되는 변경에 테스트 코드에 의해 보호를 받알 수있음
테스트 코드만 보고도 기능 명세가 될 수 있음

1. 테스팅 레벨


https://martinfowler.com/articles/microservice-testing/#conclusion-test-pyramid

  • 단위테스트 : 도메인별로 테스트

    https://dancerscode.com/posts/unit-tests/
    sut : system under test (테스트 대상, 주로 하나의 클래스)
    테스트 버블 : 협력관계에 있는 객체를 바로 실제 객체에 사용할 수 없을때 가짜로 만드는것
    예: stop, mock객체

  • 컴포넌트테스트 : 서비스 전체

  • 통합테스트(Intergration test) : 테스트하고자하는코드를 다른의존관계와 연동이 잘 됬는지
    외부시스템과 연동도 잘 되는지

  • 엔드투엔드 :UI부터 Api호출, DB에 적재 되는지등 시스템 전체에 대한 테스트

2. Junit

  • 매 단위 테스트시마다 테스트 클래스의 인스턴스가 생성되어 독립적인 테스트가 가능

  • 애노테이션을 제공해서 테스트 라이프 사이클을 관리하게 해주고 테스트 코드를 간결하게 작성하도록 지원(@afterall, @aftereach)

  • 테스트 러너를 제공해서 인텔리제이 / 이클립스 / 메이븐 등에서 테스트 코드를 쉽게 실행 가능

  • assert로 테스트 케이스의 수행 결과를 판별하게 해줍니다. →assertEquals(예상 값, 실제값)
    결과는 성공(녹색), 실패(붉은색) 중 하나로 표시해줍니다.

3. 통합테스트

3-1 테스트 코드 작성

1,2번 테스트를 위해 resources에 logback-test.xml 작성

@BeforeAll - 테스테에 한번만 실행
@BeforeEach - 테스트마다 실행

3. assertEqual : 기댓값과 실행값이 일치한지 확인해 주는 기능
4. 할인된 금액이 일치하는지 테스트
5. 마이너스가 될 경우 예외를 던져줘야하는데 그거에 대한 코드가 없기때문에 오류가 뜬다

5,6,7 테스트를 위해 FixedAmountVoucher에다가 각각 경우에 대해 예외처리해주는 코드를 추가해준다.
7번에 @Disabled는 해당 테스트를 건너뛰는 효과가 있음

더 편리한 테스트를 제공해주는 Hamcrest 이용

  1. Hamcrest을 사용하기 위해 임포트 해줘야함
  2. 기존에 사용했던 assertEquals대신에 assertThat 사용
  • equalTo, is : 결과값이 2 여야한다
  • anyOf : 결과값이 2 이거나 1
  1. 컬렉션에 대해 테스트 할 수 있도록 편리한 기능 제공
  • hasSize : 리스트의 크기
  • gresterThan: 모든 값이 1을 넘는가?
  • containsInAnyOrder: 순서에 상관없이 해당값들을 포함하고 있는가?
  • hasItem: 해당값을 가지고 있는가 ?
    greatherThanOrEqyalTo가 있으므로 2보다 크거가 같은 값을 가지고있는가?

실제값과 기대값을 매칭
햄클래스

3-2 Mock Object(모의 객체)

  • 목 오브젝트는 행위 검증(behavior verification)을 사용하고, stub을 포함한 다른 대역들은 상태 검증(state verification)을 사용
  • 호출에 대한 기대를 명세
  • Mock Object 생성을 도와주는 Test Framework
    - Mockito
    • JMock
    • EasyMock.
  1. Order.class에다가 값들을 얻어오기 위한 get메서드 추가

2.OrderServiceTest 작성

  1. Stub 이용
  2. Mock 이용 (import static org.mockito.Mockito.*;)
  • voucherService와 OrderRepository에 대한 Mock 생성
  • mock은 when으로 기술한 부분만 동작함
    voucherServiceMock객체에서 우리가 만든 fixedAmountVoucher 에 아이디를 가지고 올라하면 fixedAmountVoucher가 리턴되는 상황을 만들었다.
  • 오더서비스를 만들고 오더서비스를 우리가 테스트 하는 내용을 실행
    오더에대한 사태검증 할수 있고 오더서비스안에서 사용되는 바우처서비스가 어떤 행동을 하는지 어떤 메서드가 호출이 되는지를 검증을함
  • 특정한순서를 보장해서 수행되어 져야 한다면, inOrder을 이용하면 각각의 목들이 어떤 순서대로 호출되어져야하는지까지 판단 가능

    Inorder을 추가함으로써 OrderService에서 작성한 순서대로 수행이 되어야함. 만약에 순서가 바뀐다면, 오류가 뜸

우리는 목오브젝트의 도움을 받아서 별도의 코드추가없이 메서드 호출여부 확인할수있고 어떻게 동작이 수행이 되어지는지 확인이 가능

Spring의 JUnit 5 지원

  • 단위 테스트 지원
    - Mock Objects 지원
    - General Testing Utilities
    - Spring MVC Testing Utilities
  • 통합 테스트 지원
    - Spring TestContext 프레임워크
    Spring TestContextFramework를 이용하면 테스트환경에서 applicationContext를 에노테이션만 이용하여 쉽게 만들 수 있다. 캐쉬기능이 되기때문에 같은 내용의 컨테이너라면 매번 만들 필요 없이 기존에 캐쉬된것을 이용하여 빠르게 테스트를 구동 가능

통합테스트

@SpringJUnitConfig
@ActiveProfiles("test")
public class kdtSpringContextTests {

    @Configuration
    @ComponentScan(basePackages = {"org.prgrms.kdt.order", "org.prgrms.kdt.voucher"})
    static class Config{

    }
    @Autowired
    ApplicationContext context;

    @Autowired
    OrderService orderService;

    @Autowired
    VoucherRepository voucherRepository;

    @Test
    @DisplayName("applicationContext가 생성 되어야한다. ")
    public void testApplicationContext(){
        assertThat(context, notNullValue());
    }

    @Test
    @DisplayName("VoucherRepository가 빈으로 등록 되어야한다 . ")
    public void testVoucherRepositoryCreation(){
        var bean = context.getBean(VoucherRepository.class);
        assertThat(bean, notNullValue());
    }

    @Test
    @DisplayName("orderService를 사용해서 주문을 생성 할 수 있다.  ")
    public void testOrderService(){
        //Given
        var fixedAmountVoucher = new FixedAmountVoucher(UUID.randomUUID(),100);
        voucherRepository.insert(fixedAmountVoucher);

        //When
        var order = orderService.createOrder(UUID.randomUUID(), List.of(new OrderItem(UUID.randomUUID(),200,1)),fixedAmountVoucher.getVoucherId());

        //Then
        assertThat(order.totalAmount(),is(100L)); //totalAmount 값이 Long 이기 때문에 Long타입으로 변환
        assertThat(order.getVoucher().isEmpty(), is(false));
        assertThat(order.getVoucher().get().getVoucherId(), is(fixedAmountVoucher.getVoucherId()));
        assertThat(order.getOrderStatus(),is(OrderStatus.ACCEPTED));
    }
}
  • 이전에는 Mock을 이용했다면 통합테스트는 applicationContext에서 빈들을 꺼내어 테스트 applicationcontext 를 만들어줌
  • @SpringJUnitConfig를 이용해 TestContextFramework이 만들어짐
    두개를 포함하고 있음
    @ExtendWith(SpringExtension.class)
    @ContextConfiguration /(classes = {AppConfiguration.class})
  • @ActiveProfiles("test") 를통해 맞는 레포지토리 프로파일 엑티브
  • @ComponentScan을 통해 각각의서비스와 레포지토리를 빈에 등록
profile
꿈꿈

0개의 댓글