Mockito에서 Multi-Stubbing 적용하기

Overview

팀에서 초기부터 Junit5를 적용하다보니, MockitoExtension을 제대로 제공받지(?) 못했다.

그래서 오픈소스로 공개되어 있던 것 중에 하나를 그냥 복사해서 프로젝트내에 class를 두고 사용했다.

그러다가 최근에 SpringBoot에서 Junit5를 지원1 해주는 김에 SpringBoot로 의존성 관리하도록 바꿨다.

그랬더니 자연스럽게 Mockito 버전도 올라가고, MockitoExtension이 제공되고 있었다.

사실 해당 Extension이 제공된 것은 2018년 3월부터였는데2 참 업그레이드도 안했다 싶었다.

 

문제발생 및 해결

어쨌거나 그랬더니 문제가 몇 가지 발생했는데,

첫 번째로 발생했던 문제는 Mockito UnnecessaryStubbingException에서 한 번 포스팅했었고,

오늘 발생한 문제는 Multi-Stubbing에 대한 문제였다.

이렇게 여러 가지 파라미터에 대한 응답을 각각 Stubbing하고,

각 테스트에서 해당 파라미터를 활용해서 응답값을 조절하는 방식3 을 썼다.

그런데 아래와 같은 오류가 발생했다.

아마도, 예전부터 Mockito가 조금 느슨한 Stubbing을 제공하고 있어서 문제가 좀 있었던 모양이다.4

그래서 이제부터는 Strict하게 Stubbing을 체크해서, 여러 개 정의 되거나 불필요한 것이 있으면 Test Fail로 처리해버린다.

서로 다른 파라미터로 요청하는 Stubbing은 다른 것으로 봐야하는 것이 아닌가 싶은 생각5 은 나만의 문제는 아닌 듯 하다.

어찌됐거나 given().will()혹은 when().then() 대신에 will().given(), doReturn().when()을 사용하라고 권고한다.

단순히 순서를 바꾼 것에 지나지 않는 것 같지만, 하나는 Strict Mode로 다른 것은 Lenient Mode로 동작한다.6

아래처럼 수정하면 테스트가 정상적으로 동작한다.

 

One More Thing

참고로 when().then()doReturn().when()은 파라미터 구조가 약간 다르다.

만약 아래와 같은 오류가 발생했다면, 괄호의 위치를 잘못 썼을 가능성이 크다.

괄호에 대한 오타가 난 것인데, 컴파일 단계에서 오류가 안나다니… 뭔가 잘못 설계됐다는 생각이 든다.

위의 정상적인 코드와 아래의 잘못된 코드가 무슨 차이가 있는지는 잘 찾아보도록 하자.

 


  1. https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes#junit-5 
  2. https://github.com/mockito/mockito/blob/release/2.x/doc/release-notes/official.md#2180 
  3. 특히, 이런 방식은 MockServer같은 것으로 정의해두고 쓸 때에 유용한 방법이다. 
  4. 사실 이런 느슨한 Stubbing 덕분에 jmock이나 easymock을 제치고 권좌에 앉았다고 생각이 들긴 함 
  5. https://github.com/mockito/mockito/issues/1522 
  6. 사실은 Lenient 모드로 동작한다기보다는 기존의 동작을 수정하지 않았다는 것이 더 맞는 말이다. 

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다