[Spring] core3 -Test

호호빵·2022년 6월 20일
0

Spring

목록 보기
8/24

테스트의 필요성

블랙박스 테스트

개발자 테스트

JUnit 단위 테스트

단위테스트 : 프로그램을 작은 단위로 쪼개서 각 단위가 정확하게 동작하는지 검사하고 이를 통해 문제 발생 시 정확하게 어느 부분이 잘못되었는지를 재빨리 확인할 수 있게 해줌

  • JUnit : 자바 프로그래밍 언어용 단위 테스트 프레임워크
  • build.gradle 에 이미 추가되어 있음
  • 단축키 : cmd + sh + O 파일찾기
  • 테스트 에러 시 뒤의 내용 진행 x
class ProductTest {
    @Test
    @DisplayName("정상 케이스")
    void createProduct_Normal() {
        // given
        Long userId = 100L;
        String title = "오리온 꼬북칩 초코츄러스맛 160g";
        String image = "https://shopping-phinf.pstatic.net/main_2416122/24161228524.20200915151118.jpg";
        String link = "https://search.shopping.naver.com/gate.nhn?id=24161228524";
        int lprice = 2350;

        ProductRequestDto requestDto = new ProductRequestDto(
                title,
                image,
                link,
                lprice
        );

        // when
        Product product = new Product(requestDto, userId);

        // then
        assertNull(product.getId());
        assertEquals(userId, product.getUserId());
        assertEquals(title, product.getTitle());
        assertEquals(image, product.getImage());
        assertEquals(link, product.getLink());
        assertEquals(lprice, product.getLprice());
        assertEquals(0, product.getMyprice());
    }

Edge 케이스 테스트

입력 가능한 모든 케이스 고려해보기

  • 1) 회원 아이디 (userId) 가 null 로 들어온다면, 등록된 상품은 어떤 회원의 상품이 되는거지?
  • 2) 회원 아이디 (userId) 가 마이너스 값이라면, 등록된 상품은 어떤 회원의 상품이 되는거지? (DB 테이블 Id 의 경우 마이너스 값을 갖지 않음)

Mock

통합 테스트

  • (Integration Test)
  • 두 개 이상의 모듈이 연결된 상태를 테스트
  • 모듈 간의 연결에서 발생하는 에러 검증 기능

End to End TEST(E2E)

  • 실제 사용자의 실행 환경과 거의 동일한 환경에서 테스트 진행(블랙박스 테스팅)

Annotation @

@SpringBootTest

  • 스프링 부트가 제공하는 테스트 어노테이션.
  • 테스트 수행 시 스프링이 동작함
    • Spring IoC 사용 가능
    • Repository 사용해 DB CRUD 가능
  • End to End 테스트도 가능
    • Client 요청 → Controller → Service → Repository → Client 응답

@Order(1), @Order(2)

  • 테스트의 순서를 정할 수 있음

관심상품 통합테스트 설계

  1. 신규 관심상품 등록
    • 회원 Id 는 임의의 값
  2. 신규 등록된 관심상품의 희망 최저가 변경
    • 1번에서 등록한 관심상품의 희망 최저가를 변경
  3. 회원 Id 로 등록된 모든 관심상품 조회
    • 조회된 모든 관심상품 중 1번에서 등록한 관심상품이 존재하는지?
    • 2번에서 업데이트한 내용이 잘 반영되었는지?

관심상품 통합테스트 구현

ProductIntegrationTest

@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());
    }
}

회원가입 후 관심상품 등록 테스트

  • 기존 ProductIntegration
    관심상품 등록 -> 관심상품 업뎃 -> 관심상품 조회
  • UserProductIntegrationTest
    회원가입 전 관심상품 등록(실패) -> 회원가입 -> 가입된 회원으로 등록
    -> 업뎃 -> 조회
추가!
public class UserProductIntegrationTest {

    @Autowired
    UserService userService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    ProductService productService;


    Long userId = null;
    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
        Exception exception = assertThrows(IllegalArgumentException.class, () -> {
            productService.createProduct(requestDto, userId);
        });

        // then
        assertEquals("회원 Id 가 유효하지 않습니다.", exception.getMessage());
    }

    @Test
    @Order(2)
    @DisplayName("회원 가입")
    void test2() {
        // given
        String username = "르탄이";
        String password = "nobodynoboy";
        String email = "retan1@spartacodingclub.kr";
        boolean admin = false;

        SignupRequestDto signupRequestDto = new SignupRequestDto();
        signupRequestDto.setUsername(username);
        signupRequestDto.setPassword(password);
        signupRequestDto.setEmail(email);
        signupRequestDto.setAdmin(admin);

        // when
        User user = userService.registerUser(signupRequestDto);

        // then
        assertNotNull(user.getId());
        assertEquals(username, user.getUsername());
        assertTrue(passwordEncoder.matches(password, user.getPassword()));
        assertEquals(email, user.getEmail());
        assertEquals(UserRole.USER, user.getRole());

        userId = user.getId();
    }
    
    @Test
    @Order(3)
    
    @Test
    @Order(4)
    
    @Test
    @Order(5)
}
profile
하루에 한 개념씩

0개의 댓글