org.mockito.exceptions.misusing.UnnecessaryStubbingException: Unnecessary stubbings detected. Clean & maintainable test code requires zero unnecessary code. Following stubbings are unnecessary (click to navigate to relevant line of code):

황상익·2024년 4월 8일

Mockito 사용중 Unnecessary Stubbing Exception 해소하기
Spring Boot에서 JUnit5와 이에 포함된 Mockito Core 3.x 버전을 사용할 때 아래와 같이 UnnecessaryStubbingException 에러가 나면서 테스트코드가 실패하는 경우가 있습니다.

mockito-core버전이 1.x일 때 없었던 Strictness(테스트코드의 엄격성)을 규정하기 위해 생긴 에러이며, mockito-core 2.x 버전에서 도입되었습니다.

테스트코드의 엄격성은 다음 요소들을 보장해 줍니다.

테스트코드에서 사용되지 않는 stub (when/thenReturn)을 줄여줍니다.
테스트코드에서 불필요한 코드 중복을 없애주고 이를 통해 필요없는 테스트 코드 역시 줄여줍니다.
죽은 코드를 제거하면서 생기는 불필요한 테스트를 없애도록 도와줍니다.
이를 통해 디버깅 편의성과 생산 효율을 올려줍니다.

해결 방법
1. Mockito-core 버전을 1.x나 2.x로 내리기
1) 최악의 해법이지만, 수정되어야 하는 코드가 많을 경우 어쩔 수 없이 선택해야하는 경우의 수입니다.
2) 2.x 에서는 엄격성 개념이 도입되었지만, 테스트에 아래와 같이 MockitoSettings를 지정해주면 엄격성을 우회해서 테스트할 수 있습니다.

  1. lenient() 메서드를 앞에 추가하기
    doReturn, when 등의 앞에 lenient()를 추가해서 해당 stubbing이 미사용될 수 있음을 표시합니다.
    일반적으로, @BeforeEach 처럼 전체 테스트에 적용되어야 하는 stubbing이 일부 엣지 케이스에서 미사용될때 사용하는 것이 좋습니다.
    남발하게 된다면, 과한 코드의 중복을 보게 되어 Mockito에서 추구하고자 한 테스트의 개선에 도움이 되지 않습니다.
// lenient()를 붙여서 mocking 결과를 항상 사용하진 않음을 표시합니다.
lenient().doReturn(fixedClock.instant()).when(clock).instant();
lenient().doReturn(fixedClock.getZone()).when(clock).getZone();
  1. 필요없는 stubbing을 제거하기
    말 그대로 필요없는 when, doReturn, doThrow 등을 제거합니다.
    불필요한 테스트가 줄어들고, 중복 mocking이 줄어들기 때문에 나중에 코드를 수정하는 사람이 테스트코드를 이해하는데 편해집니다.

나의 경우 2번째에 해당 하는 case였다.

@Test
@DisplayName("계좌 생성 실패")
void createAccount_Fail(){
    AccountUser user = new AccountUser().builder()
            .name("Hwang")
            .build();
    user.setId(2L);

    // Unnecessary stubbing 제거
    // given(accountRepository.findById(anyLong())).willReturn(Optional.empty());

    AccountException accountException = assertThrows(AccountException.class,
            ()-> accountService.createAccount(1L, 10000L));

    assertEquals(ErrorCode.USER_NOT_FOUND, accountException.getErrorCode());
}
profile
개발자를 향해 가는 중입니다~! 항상 겸손

0개의 댓글