inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링부트로 직접 만들면서 배우는 대규모 시스템 설계 - 게시판

HotArticle 관련 테스트 중에 질문드립니다.(verify, handle 관련)

해결된 질문

86

잉도잉

작성한 질문수 1

0

안녕하세요. 강의 열심히 듣고 있습니다.

Hot-article 관련 테스트 코드 중, verify 메소드에 대해 잘 몰라서 하는 질문일수도 있겠으나 헷갈리어 질문 드립니다.

HotArticleServiceTest.java 코드를 작성중에

@Test
void handleEventIfScoreUpdatableEventTest() {
    // given
    Event event = mock(Event.class);
    given(event.getType()).willReturn(mock(EventType.class));

    EventHandler eventHandler = mock(EventHandler.class);
    given(eventHandler.supports(event)).willReturn(true);
    given(eventHandlers.stream()).willReturn(Stream.of(eventHandler));

    // when
    hotArticleService.handleEvent(event);

    // then
    verify(eventHandler, never()).handle(event);
    verify(hotArticleScoreUpdater).update(event, eventHandler);
}

위의 코드에서, verify(eventHanler, never()).handle(event); 로 검증하는 부분이 왜 never()가 되는걸까요?

강의중에 eventHandler가 바로 불리지 않는다고 말씀하시긴 하셨는데, HotArticleService.javahandleEvent() 메소드 안에서 hotArticleScoreUpdater.update(event, eventHandler) 를 호출하면 update()에서 전달한 eventHandler handle()메소드를 결국에는 사용하게 되지 않나요?

verify가 외부클래스인 HotArticleScoreUpdater의 메소드에서 사용하는거까지는 검지하지 못하기 때문일까요?

 

java mysql spring-boot kafka redis

답변 2

0

쿠케

인재님, 안녕하세요!

일단 강의 열심히 잘 들어주셔서 감사합니다.

 

verify가 외부클래스인 HotArticleScoreUpdater의 메소드에서 사용하는거까지는 검지하지 못하기 때문일까요?

위 내용이 맞습니다.

HotArticleServiceTest는 HotArticleService에 대한 동작에 대해서만 단위 테스트하고자 하는 것이 의도입니다.

내부 의존성까지 모두 통합해서 테스트하진 않습니다.

 

    @InjectMocks
    HotArticleService hotArticleService;
    @Mock
    List<EventHandler> eventHandlers;
    @Mock
    HotArticleScoreUpdater hotArticleScoreUpdater;

위 내용을 보시면, Mockito라는 테스트 프레임워크를 통해서 HotArticleService에 의존성으로 선언된 eventHandlers와 hotArticleScoreUpdater는 모두 mock 객체로 주입된다는 것을 알 수 있습니다.

@InjectMocks 선언된 객체에 @Mock 선언된 객체들이 주입되기 때문입니다.

 

쉽게 생각하면,

HotArticleScoreUpdater는 실제 저희가 작성한 클래스의 인스턴스가 생성되어서 의존성으로 주입된 것이 아니라,

HotArticleScoreUpdater의 메소드들이 정의된 어떠한 인터페이스가 mock 객체로 구현되었고, 이러한 mock 객체가 HotArticleSerivce에 주입되었다고 생각하시면 됩니다.

mock 객체이기 때문에 verify를 통해서 어떠한 메소드가 호출되었는지 추적할 수 있는 것이고요.

 

즉, HotArticleService의 메소드를 호출한다고 해서, 의존성으로 가지고 있는 HotArticleScoreUpdater의 실제 코드(eventHandler.handle)가 수행되는 것은 아닙니다.

물론, HotArticleScoreUpdater를 mock 객체가 아니라 실제 객체를 생성 및 주입하여 통합 테스트로 수행한다면 연계해서 호출되는 상황까지 만들어낼 수 있겠지만,

지금 테스트하고자 하는 것은 HotArticleService 입니다.

HotArticleService에 대해 단위 테스트로 수행하기 때문에 내부 의존성까지 통합해서 테스트하는게 아니라 HotArticleService의 동작만 테스트한다고 봐주시면 됩니다!

HotArticleScoreUpdater를 테스트하고 싶다면, HotArticleScoreUpdaterTest로 테스트하면 되는 것입니다.

 

테스트의 경계에 대해서 고민해보시면 좋을 것 같네요!

당장 확인이 필요한 부분만 테스트하고, 그렇지 않은 부분은 mock 객체를 활용하여 테스트를 간소화하는 것이라고 생각하셔도 될 것 같습니다!

 

혹시 더 궁금한 점 있으시면 편히 문의 주세요!

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. 이인재님.

질문하신 내용을 바탕으로 verify 메소드 사용 및 테스트 코드 작성에 대해 설명드리겠습니다. Mockitoverify 메소드는 예상한 특정 메소드의 호출 여부를 검증하는 데 사용됩니다.

테스트 코드의 핵심 이해:

  1. verify(eventHandler, never()).handle(event);:

    • 이 부분은 eventHandlerhandle 메소드가 호출되지 않았는지를 검증합니다. 즉, 이 테스트에서는 eventHandlerhandle 메소드가 직접적으로 호출되어서는 안 된다는 것을 의미합니다. 이와 관련해서 혼동이 있을 수도 있지만, 강의에서 설명한 것처럼 eventHandler는 직접 호출되지 않고 조건을 만족할 때만 호출되는 것으로 보입니다.
  2. verify(hotArticleScoreUpdater).update(event, eventHandler);:

    • hotArticleScoreUpdaterupdate 메소드가 특정 조건에서 올바르게 호출되었는지를 확인합니다. update 메소드 내부에서 eventHandlerhandle 메소드가 호출될 수 있지만, 테스트의 목적은 주어진 조건에서 eventHandlerhandle 메소드를 직접적으로 호출하지 않는지를 검증하는 것입니다.

never()의 의미:

  • never()는 해당 메소드가 전혀 호출되지 않았음을 확인합니다. 따라서 eventHandlerhandle 메소드가 hotArticleService.handleEvent 호출 동안 직접적으로 호출되지 않아야 한다는 것을 보장합니다.

텐디아에게 제공된 코드에서는 eventHandlerupdate 메소드에 전달되더라도 직접 handleEvent 메소드에서 실행되지 않도록 하는 로직이 포함되어 있는지 검사하는 것이 목적입니다. 이러한 검증은 테스트 케이스의 특정 요구 사항에 따라 다르게 설정될 수 있습니다.

추가적인 테스트 작성 시 고려사항:

  • 핵심 로직이 외부 클래스에서 호출되는지를 검증할 때는 해당 클래스 내에서의 기대 동작을 이해하는 것이 중요합니다. 테스트의 목적은 주로 의도한 로직이 정확히 실행되는지를 보장하는 데 있기 때문에, 테스트가 정확히 어떤 시나리오를 검증하는지를 명확히 이해해야 합니다.

관련 주제를 더 알아보고 싶으시다면, 아래 유사한 질문과 답변을 참고해 보시면 좋겠습니다:
- Mockito를 활용한 테스트 사례에 대한 논의

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

@Version 어노테이션이 붙은 필드는 낙관적 락이든 비관적 락이든 업데이트가 됩니다.

0

31

1

consumer에서 에러가 발생할 경우 데이터 유실 문의

0

47

2

게시글 테스트 데이터 삽입

0

51

2

정렬, 필터, 검색 등의 조건이 붙을 경우 최적화할 수 있는 방법이 무엇이 있을까요?

0

104

2

좋아요 기능 정합성 보장 방법

0

98

2

좋아요 동시성처리 최적의 선택?

1

136

2

프론트엔드 msa 환경 api 주소 통합? 과 서버끼리 통신 방식에대해

0

92

2

안녕하세요 무한스크롤 강의듣다가 질문이 있습니다.

0

59

1

조회수 조회 로직 질문

1

67

2

비로그인 유저도 어뷰징 방지 정책

1

72

2

CommentServiceTest의 테스트 로직 질문

0

54

2

무한 스크롤 방식에서 페이지 번호 방식 쿼리의 문제점 의문

1

74

2

path 쿼리 관련 질문드립니다!

0

60

2

antigravity 에디터를 쓰신다면 종료해주세요

1

123

0

프로젝트 구조

0

88

2

article_like_count api test

0

79

2

이벤트 페이로드 객체의 생성 방식이 팩토리 메서드 패턴이 아닌 빌더 패턴인 이유가 궁금합니다!.

0

104

2

[33. 좋아요 수 구현] 에서 테스트 하는 화면 동시성 문제

0

91

2

findByPath에서 articleId로도 검색을 해야 할 것 같아요.

0

92

3

jpa ddl-auto none을 하는 이유와 join 방법

0

97

2

팩터리 메소드와 response 객체 사용 이유가 궁금합니다!

0

90

2

커서 기반 페이지네이션 과 무한 스크롤링

0

110

2

게시글 생성 로직에서 오류 발생시 redis 게시글 수 되돌리기

0

97

2

멀티 모듈이 아닌 MSA 환경에서 common

0

156

2