kotlin/Test

Mockito를 활용한 모의 객체 설정: thenReturn vs doReturn

Kyleslabs 2024. 12. 2. 23:31

thenReturn

  • 사용법:
when(mock.method()).thenReturn(value)
  • 용도:
    • 주로 open 메서드나 인터페이스의 메서드를 모의할 때 사용합니다.
  • 특징:
    • 메서드 호출이 실제로 발생해야 하며, null이 아닌 값을 반환해야 합니다.
  • 동작 방식:
    • Mockito가 바이트코드를 조작하여 메서드 호출을 가로채는 방식으로 동작합니다.
    • 그렇기 때문에 메서드 호출이 실제로 발생해야 하며, final, private, static 메서드에는 사용할 수 없습니다.
  • 제약:
    • final, private, static 메서드에는 사용할 수 없습니다.
  • 장점:
    • when-thenReturn로 가독성과 명확한 의도를 보여줄 수 있고, 디버깅 정보가 명확하다.
    • 가독성: 코드가 직관적이고 읽기 쉽습니다.
    • 일관성: 일반적인 Mockito 사용 패턴과 일치하여 팀 내 일관성을 유지할 수 있습니다.
    • 명확한 의도: "이 메서드가 호출될 때 이 값을 반환한다"는 의도를 명확히 전달합니다.
    • 디버깅 용이성: 메서드 호출 시점에 대한 디버깅 정보가 명확합니다.
  • 예제:
    open class UserService {
        open fun getUserName(userId: Int): String {
            return "Real User Name"
        }
    }
    
    val mockUserService = mock(UserService::class.java)
    `when`(mockUserService.getUserName(1)).thenReturn("Mock User Name")

 

doReturn

  • 사용법:
doReturn(value).`when`(mock).method()
  • 용도:
    • final, private, static 메서드와 같이 when 구문을 사용할 수 없는 상황에서 사용합니다.
  • 특징:
    • 메서드가 호출되지 않아도 반환값을 설정할 수 있습니다.
  • 동작 방식:
    • 메서드 호출 전 반환 값을 직접 설정하여 동작을 정의합니다.
    • 이 방식은 바이트코드 조작을 필요로 하지 않으므로, final 메서드에도 적용할 수 있습니다.
  • 제약:
    • final 메서드 등에서도 사용할 수 있으므로 제약이 적습니다.
  • 예제:
    class UserService {
        fun getUserName(userId: Int): String {
            return "Real User Name"
        }
    }
    
    val mockUserService = mock(UserService::class.java)
    doReturn("Mock User Name").`when`(mockUserService).getUserName(1)

결론

  • doReturn은 더 유연하고 제약이 적기 때문에 모든 상황에서 사용할 수 있을 것처럼 보이지만, thenReturn은 코드의 가독성, 일관성, 명확한 의도 전달 측면에서 여전히 중요한 역할을 합니다.
  • open 메서드나 인터페이스 메서드를 모의할 때는 thenReturn을 사용하는 것이 일반적입니다.
  • 각 상황에 맞게 가장 적합한 방법을 선택하는 것이 중요합니다. final 메서드나 특정 상황에서는 doReturn을 사용해야 합니다.