ysk(0soo)
Lifealong
ysk(0soo)
전체 방문자
오늘
어제
  • 분류 전체보기 (238)
    • Java (50)
      • whiteship-java-study (11)
      • Java (28)
      • time (6)
    • Spring (68)
      • JPA (15)
      • Spring (1)
      • SpringBoot (1)
      • SpringMVC (6)
      • Spring Security (22)
      • Jdbc (1)
      • RestDocs (14)
      • log (6)
    • Kotlin (3)
    • Web (2)
      • nginx (1)
    • Database (14)
      • MySQL (5)
      • PostgreSQL (1)
      • SQL (1)
      • Redis (4)
    • C, C++ (0)
    • Git (1)
    • Docker (2)
    • Cloud (3)
      • AWS (3)
    • 도서, 강의 (0)
      • t5 (0)
    • 기타 (7)
      • 프로그래밍 (1)
    • 끄적끄적 (0)
    • CS (14)
      • 운영체제(OS) (2)
      • 자료구조(Data Structure) (9)
    • 하루한개 (12)
      • 우아한 테크코스-10분테코톡 (12)
    • 스터디 (12)
      • 클린 아키텍처- 로버트마틴 (2)
      • JPA 프로그래밍 스터디 (10)
    • 테스트 (34)
      • JUnit (19)
      • nGrinder (2)
      • JMeter (0)
    • Infra (3)
    • 프로그래머스 백엔드 데브코스 3기 (0)
    • 디자인 패턴 (3)
    • Issue (4)
    • system (1)
      • grafana (0)
      • Prometheus (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • github

공지사항

인기 글

태그

  • 정규표현식
  • StructuredConcorrency
  • restdocs custom
  • tree
  • VirtualThread Springboot
  • nGrinder
  • DataJpaTest
  • querydsl
  • AuthenticationException
  • 가상 스레드
  • AccessDecisionManager
  • 동시성 제어
  • AccessDecisionVoter 커스텀
  • junit5
  • jpa
  • node exporter basic auth
  • 가상 스레드 예외 핸들링
  • nginx basic auth
  • java
  • 동등성
  • scope value
  • restdocs enum
  • FilterSecurityInterceptor
  • UserDetailsService
  • mysql
  • 동일성
  • 구조화된 동시성
  • 인가(Authorization) 처리
  • 트랜잭션
  • LocalDateTime

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ysk(0soo)

Lifealong

테스트/JUnit

JUnit5 - Java에서의 단위테스트5 Mock, Mockito, Stup

2022. 8. 21. 21:55

Mock 객체 Stubbing

stub이란 토막,꽁초,남은부분,몽당연필.. 이라는 뜻으로 dummy객체가 마치 실제로 동작하는 것 처럼 보이도록 만들어놓은 것

  • 즉 Mock 객체의 행동을 조작하는 것

모든 Mock 객체의 행동

  • Null을 리턴한다. (Optional 타입은 Optional.empty 리턴. 즉 비어있는 옵셔널 객체)
  • Primitive 타입은 기본 Primitive 값.
  • 콜렉션은 비어있는 콜렉션.
  • Void 메소드는 예외를 던지지 않고 아무런 일도 발생하지 않는다.
  • 예제1
  • memberService.findById(1L) member 객체를 나오게 할라면 다음과 같이 쓰면 된다.
    • 만약 2L, 3L 등 다른 member 객체를 나오게 한다면 오류가 난다.
      • 1L로만 member를 나오게 했기 때문
    • 즉 when().thenReturn은 mock 객체를 직접 핸들링한다
    • org.mockito.ArgumentMatchers.any(); 메서드를 사용하면
      항상 같은 객체가 나온다 (아무 값이나 상관 없다).
  • @Test void createNewStudy(@Mock MemberService memberService, @Mock StudyRepository studyRepository) { Member member = new Member(); member.setId(1L); member.setEmail("youngsoo@naver.com"); Optional<Member> byId = memberService.findById(1L); when(memberService.findById(1L)) .thenReturn(Optional.of(member)); Study study = new Study(10, "java"); Optional<Member> findById = memberService.findById(1L); assertEquals("youngsoo@naver.com", findById.get().getEmail()); }
  • 예외를 던지는 doThrow() org.mockito.Mockito.doThrow;
    • doThrow(new IllegalArgumentException())
              .when(memberService).validate();
      
      assertThrows(IllegalArgumentException.class, () -> {
          memberService.validate();
          });
  • 순서대로 호출하기
  • when(memberService.findById(any()))
                  .thenReturn(Optional.of(member))
                  .thenThrow(new RuntimeException())
                  .thenReturn(Optional.empty());
    • 첫번째 호출 멤버
    • 두번째 호출 런타임 익셉션
    • 세번째 호출 빈 옵셔널 객체를 내보낸다

Mockito에서는 아래의 stub메서드들을 지원.
doReturn(): Mock 객체가 특정한 값을 반환해야 하는 경우 사용

    doReturn(3).when(p).add(anyInt(), anyInt());

doNothing(): Mock 객체가 아무 것도 반환하지 않는 경우 사용(void)

@Test
public void example(){
    Person p = mock(Person.class);
    doNothing().when(p).setAge(anyInt());
    p.setAge(20);
    verify(p).setAge(anyInt());
}

doThrow(): Mock 객체가 예외를 발생시키는 경우 사용

@Test(expected = IllegalArgumentException.class)
public void example(){
    Person p = mock(Person.class);
    doThrow(new IllegalArgumentException()).when(p).setName(eq("JDM"));
    String name = "JDM";
    p.setName(name);
}

Stub의 doReturn, thenReturn의 차이

Mockito를 사용하다보면 코드들에 doThrow, doReturn등의 형식이 아닌

thenReturn(), thenThrow()등의 형식도 볼 수 있을 것이다. 둘의 차이점은 다음과 같다.

doReturn

  • 실제로 메서드를 호출하고 리턴값을 임의로 정의할 수 있다.
  • 메서드를 실제로 수행하여 메서드 작업이 오래걸릴 경우 끝날 때 까지 기다려야한다.
  • 실제 메서드를 호출하기 때문에 대상 메서드에 문제점이 있을 경우 발견할 수 있다.
doReturn(6).when(cal).add(2, 4);

thenReturn

  • 메서드를 실제로 호출하지 않으며 리턴값을 임의로 정의할 수 있다.
  • 실제 메서드를 호출하지 않기 때문에 대상 메서드에 문제점이 있어도 알 수 없다.
when(cal.add(2, 4)).thenReturn(6); 

Mock 객체 확인

Mock 객체가 어떻게 사용이 됐는지 확인할 수 있다.

  • 특정 메소드가 특정 매개변수로 몇번 호출 되었는지,
  • 최소 한번은 호출 됐는지,
  • 전혀 호출되지 않았는지
    • Verifying exact number of invocations
    • org.mockito.Mockito.verify() 메서드
    • 예제 : 멤버 서비스에서 딱 1번 notify란 메서드가 study라는 매개변수를 가지고 호출 되어야 한다
    • verify(memberService, times(1)).notify(study);
    • any()도 가능하다.
  • 어떤 순서대로 호출했는지
    • Verification in order
    • org.mockito.Mockito.inOrder(), inOrder.verify() 메서드
    • 예제 : 멤버 서비스에서 notify(study) 메소드가 notify(member) 보다 먼저 호출되어야 한다.
    • verify(memberService, times(1)).notify(study);
      verify(memberService, times(1)).notify(member);
      
      InOrder inOrder = inOrder(memberService)
      inOrder.verify(memberService).notify(study);
      inOrder.verify(memberService).notify(member);
    • 이후에 더이상 아무 액션이 일어나면 안된다 할 때는
    • verifyNoMoreInteractions(Object mocks...) 메서드
  • 특정 시간 이내에 호출됐는지
    • Verification with timeout
  • 특정 시점 이후에 아무 일도 벌어지지 않았는지
    • Finding redundant invocations

참고

  • 인프런 백기선님 강의 더 자바, 애플리케이션을 테스트하는 다양한 방법
  • https://velog.io/@seongwon97/Unit-Test-%EB%8B%A8%EC%9C%84-%ED%85%8C%EC%8A%A4%ED%8A%B8

'테스트 > JUnit' 카테고리의 다른 글

RefectionTestUtils - private 필드 값 주입, private 테스트  (0) 2022.12.13
Spring Boot JPA Test @DataJpaTest 기본 설정  (3) 2022.08.27
JUnit5 - Java에서의 단위테스트4 Mock, Mockito  (0) 2022.08.21
JUnit5 - Java에서의 단위테스트3 - 테스트 인스턴스들  (0) 2022.08.21
JUnit5 - Java에서의 단위테스트2 - 테스트 반복  (0) 2022.08.21
    '테스트/JUnit' 카테고리의 다른 글
    • RefectionTestUtils - private 필드 값 주입, private 테스트
    • Spring Boot JPA Test @DataJpaTest 기본 설정
    • JUnit5 - Java에서의 단위테스트4 Mock, Mockito
    • JUnit5 - Java에서의 단위테스트3 - 테스트 인스턴스들
    ysk(0soo)
    ysk(0soo)
    백엔드 개발을 좋아합니다. java kotlin spring, infra 에 관심이 많습니다. email : kim206gh@naver.com github : https://github.com/devysk

    티스토리툴바