[TIL] Today I Lerned - 230103

2023. 1. 3. 21:12기록/TIL

[TIL] Today I Lerned - 230103

 

230103 기록

 

프로젝트

 

어제 TIL의 연장선이기도 하다. 

오늘도 각 개인의 프로젝트의 진척도가 다르기에 기능 테스트를 위해 테스트 코드를 학습하고 적용하는데 힘을 기울였다.

 

사용 어노테이션 기능
@ExtendWith(MockitoExtension.class)
사용할 테스트 interface를 등록해서 쓸수있게 해주는 기능

해당 어노테이션 안에 MockitoExtension을 지정하여 mockito를 쓴다고 명시함

- Junit5 -
@Test
해당 메서드가 테스트 메서드란 것을 알리기위해
붙이는 어노테이션

이때 테스트 메서드의 경우 private, static 타입이 아니며
값을 리턴하면 안된다.

@DisplayName
내가 어떤 결과를 원하는지 메서드 이름에 맞춰서 호출할 수 있게 해주는 기능

@Mock
mock 객체를 생성해주는 역할

@InjsctMocks
@Mock이 붙은 mock 객체를 @InjaectMock에 넣어준다

 

 

@ExtendWith(MockitoExtension.class)  // 설정 문제, 이 선언을 해줘야 mock인식으로 run
class LikeCommentServiceTest {

    @Mock
    LikeCommentRepository likeCommentRepository;
    @Mock
    CommentRepository commentRepository;
    @Mock
    UserRepository userRepository;

    @InjectMocks  // 가짜 객체 삽입,
    LikeCommentService likeCommentService;


//....
}

 

해당 경우와 같이 service를 InjectMock으로 선언 후 Mock 어노테이션이 붙은 객체를 service에 넣어주는 식으로 사용

 

사용한 mock 기능

  • mock - 가짜 객체 사용
  • when - 가짜 객체가 사용이 되면서 호출이 되는 경우를 뜻함
    • thenReturn과 같이 사용하여 어떤 값이 호출될지 정해줌
  • Assertions -  test 결괏값 확인을 위한 객체
    • assertSame -  값이 같은 지 비교해서 True / False를 호출
    • assertThrow - 값이 exception을 반환하는 경우 해당 exception이 올바르게 반환되었는지 확인
@Test
@DisplayName("좋아요 성공 케이스")
void clickFavorite() throws Exception {

    //given
    User user = mock(User.class);
    Comment comment = mock(Comment.class);
    when(user.getUsername()).thenReturn("userA");
    when(comment.getId()).thenReturn(1L);
    when(userRepository.findByUsername(user.getUsername())).thenReturn(Optional.of(user));
    when(commentRepository.findById(comment.getId())).thenReturn(Optional.of(comment));
    when(likeCommentRepository.existsByUserAndComment(user, comment)).thenReturn(false);
    //when
    String s = likeCommentService.clickFavorite(comment.getId(), user.getUsername());

    //then
    Assertions.assertSame("좋아요를 누르셨습니다",s);
}

@DisplayName("좋아요 실패 케이스")
@Test
void clickFavoriteError() throws Exception {
    //given
    User user = mock(User.class);
    Comment comment = mock(Comment.class);
    when(user.getUsername()).thenReturn("userA");
    when(comment.getId()).thenReturn(1L);
    when(userRepository.findByUsername(user.getUsername())).thenReturn(Optional.of(user));
    when(commentRepository.findById(comment.getId())).thenReturn(Optional.of(comment));
    when(likeCommentRepository.existsByUserAndComment(user, comment)).thenReturn(true);
    //when / then
    Assertions.assertThrows(Exception.class,()->likeCommentService.clickFavorite(comment.getId(), user.getUsername()));
}

 

코드 리뷰

 

추후에 리펙토링 할 예정이지만 나왔던 이야기 정리

 

  • url의 경우 해당 경로에서 어떤 작업이 보이는지 파악하기 쉽게 작성
    • post/{postid}/comments/{comentsid} - 댓글 수정
  • 자질구레한 코드 존재
  • comment 수정 기능부터는 commentId 값을 받아서 조회하기
    • 굳이 post id를 들고올 필요 없음
  • 주최가 post인 경우 양쪽의 서비스 레이어를 참고하더라도 주최에 맞춰 PostControlle를 사용해도 상관없음
  • 의미 없는 코드 존재 - id 값을 조회하기 위해 DB접근하는 로직들
  • 엔티티 값을 통으로 생성자에 넣어주는 것은 지양하기
    • 필요 없는 값도 동시에 들어가서 추후 유지보수 하는 경우에 엉뚱한 값이 흘러들어 갈 수 있음
  • 객체, 엔티티가 중점이지만 url은 연관관계를 고려하여 설계해보기
  • 쓸데없는 쿼리를 날려 데이터베이스에 접근하는 것을 줄이기
    • 데이터베이스 접근은 자원의 낭비를 유발
  • 이중으로 접근하는 쿼리문들 제거
    • comment를 조회하기 위해 user를 조회하고 post를 조회하는 그런 쿼리문들 제거하기
  • for문 사용 → 스트림 사용으로
    • 스트림이 알고리즘 상으로 for문보다 성능이 안 좋기는 하지만 이는 현업에서 크게 지장이 갈 정도는 아님
    • 퍼포먼스 저하가 존재한다면 스트림으로 인한 이유보단 다른 로직에서 성능 저하의 부분이 존재
    • 스트림을 사용하여 가독성을 높여 유지보수가 쉽다는 점은 큰 장점
  • ResponseEntity.created(URI.create("/post/" + id). toString()). body()의 방식
    • 바로 해당 페이지로 redirect 되는 것은 아니지만 프런트 작업 시 조금 더 편함
  • 상태코드도 맞춰주기 
    • 그냥 200 / 400 / 500으로 맞추는 것이 아닌 해당 경우에 맞춰서 사용
    • 회원가입의 경우 201
    • 삭제의 경우 204
    • 상태코드를 되도록 맞춰주는 것도 RESTful 한 API 설계에 들어간다

'기록 > TIL' 카테고리의 다른 글

[TIL] Today I Lerned - 230105  (0) 2023.01.06
[TIL] Today I Lerned - 230104  (0) 2023.01.04
[TIL] Today I Lerned - 230102  (0) 2023.01.02
[TIL] Today I Lerned - 221230  (0) 2022.12.30
[TIL] Today I Lerned - 221229  (0) 2022.12.30