스프링 부트를 이용한 통합 테스트

송영재·2022년 10월 30일

Spring

목록 보기
26/45
  • 스프링 부트 이용한 통합 테스트
    • 통합 테스트
      • 여러 단위 테스트를 하나의 통합된 테스트로 수행
      • Controller → Service → Repository
    • 단위 테스트 시 스프링은 동작 안 됨 예제 코드)
      class ProductTest {
      
          @Autowired
          ProductService productService;
      
      		// ...
      
      		@Test
          @DisplayName("정상 케이스")
          void createProduct_Normal() {
      				// ...
      
      				****// 에러 발생! productService 가 null
              Product productByService  = productService.createProduct(requestDto, userId);
    • "@SpringBootTest"
      • 스프링이 동작되도록 해주는 어노테이션!
      • 테스트 수행 시 스프링이 동작함
        • Spring IoC 사용 가능
        • Repository 사용해 DB CRUD 가능
      • End to End 테스트도 가능
        • Client 요청 → Controller → Service → Repository → Client 응답
    • @Order(1), @Order(2), ...
      • 테스트의 순서를 정할 수 있음
    • Quiz) 여러분이 "ProductService → ProductRepository" 클래스를 통합 테스트 한다면, 어떤 순서로, 어떤 내용을 테스트 하시겠나요?
  • 관심상품 통합 테스트 설계
    1. 신규 관심상품 등록
      • 회원 Id 는 임의의 값
    2. 신규 등록된 관심상품의 희망 최저가 변경
      • 1번에서 등록한 관심상품의 희망 최저가를 변경
    3. 회원 Id 로 등록된 모든 관심상품 조회
      • 조회된 모든 관심상품 중 1번에서 등록한 관심상품이 존재하는지?
      • 2번에서 업데이트한 내용이 잘 반영되었는지?
  • 관심상품 통합 테스트 구현
    • [코드스니펫] test > integration > ProductIntegraitonTest
      import com.sparta.springcore.dto.ProductMypriceRequestDto;
      import com.sparta.springcore.dto.ProductRequestDto;
      import com.sparta.springcore.model.Product;
      import com.sparta.springcore.service.ProductService;
      import org.junit.jupiter.api.*;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;
      
      import java.util.List;
      
      import static org.junit.jupiter.api.Assertions.assertEquals;
      import static org.junit.jupiter.api.Assertions.assertNotNull;
      
      @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
      @TestInstance(TestInstance.Lifecycle.PER_CLASS)
      @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
      class ProductIntegrationTest {
          @Autowired
          ProductService productService;
      
          Long userId = 100L;
          Product createdProduct = null;
          int updatedMyPrice = -1;
      
          @Test
          @Order(1)
          @DisplayName("신규 관심상품 등록")
          void test1() {
              // given
              String title = "Apple <b>에어팟</b> 2세대 유선충전 모델 (MV7N2KH/A)";
              String imageUrl = "https://shopping-phinf.pstatic.net/main_1862208/18622086330.20200831140839.jpg";
              String linkUrl = "https://search.shopping.naver.com/gate.nhn?id=18622086330";
              int lPrice = 77000;
              ProductRequestDto requestDto = new ProductRequestDto(
                      title,
                      imageUrl,
                      linkUrl,
                      lPrice
              );
      
              // when
              Product product = productService.createProduct(requestDto, userId);
      
              // then
              assertNotNull(product.getId());
              assertEquals(userId, product.getUserId());
              assertEquals(title, product.getTitle());
              assertEquals(imageUrl, product.getImage());
              assertEquals(linkUrl, product.getLink());
              assertEquals(lPrice, product.getLprice());
              assertEquals(0, product.getMyprice());
              createdProduct = product;
          }
      
          @Test
          @Order(2)
          @DisplayName("신규 등록된 관심상품의 희망 최저가 변경")
          void test2() {
              // given
              Long productId = this.createdProduct.getId();
              int myPrice = 70000;
              ProductMypriceRequestDto requestDto = new ProductMypriceRequestDto(myPrice);
      
              // when
              Product product = productService.updateProduct(productId, requestDto);
      
              // then
              assertNotNull(product.getId());
              assertEquals(userId, product.getUserId());
              assertEquals(this.createdProduct.getTitle(), product.getTitle());
              assertEquals(this.createdProduct.getImage(), product.getImage());
              assertEquals(this.createdProduct.getLink(), product.getLink());
              assertEquals(this.createdProduct.getLprice(), product.getLprice());
              assertEquals(myPrice, product.getMyprice());
              this.updatedMyPrice = myPrice;
          }
      
          @Test
          @Order(3)
          @DisplayName("회원이 등록한 모든 관심상품 조회")
          void test3() {
              // given
              
              // when
              List<Product> productList = productService.getProducts(userId);
      
              // then
              // 1. 전체 상품에서 테스트에 의해 생성된 상품 찾아오기 (상품의 id 로 찾음)
              Long createdProductId = this.createdProduct.getId();
              Product foundProduct = productList.stream()
                      .filter(product -> product.getId().equals(createdProductId))
                      .findFirst()
                      .orElse(null);
              
              // 2. Order(1) 테스트에 의해 생성된 상품과 일치하는지 검증
              assertNotNull(foundProduct);
              assertEquals(userId, foundProduct.getUserId());
              assertEquals(this.createdProduct.getId(), foundProduct.getId());
              assertEquals(this.createdProduct.getTitle(), foundProduct.getTitle());
              assertEquals(this.createdProduct.getImage(), foundProduct.getImage());
              assertEquals(this.createdProduct.getLink(), foundProduct.getLink());
              assertEquals(this.createdProduct.getLprice(), foundProduct.getLprice());
              
              // 3. Order(2) 테스트에 의해 myPrice 가격이 정상적으로 업데이트되었는지 검증
              assertEquals(this.updatedMyPrice, foundProduct.getMyprice());
          }
      }

0개의 댓글