Mockito-doReturn ()과 when ()의 차이점


196

현재 Mockito를 사용하여 컨트롤러 메소드를 테스트하려는 Spring MVC 응용 프로그램에서 서비스 계층 객체를 조롱하는 과정에 있습니다. 그러나 Mockito의 세부 사항을 읽었을 때 방법이doReturn(...).when(...) 이와 동일 습니다 when(...).thenReturn(...). 그래서, 내 질문은 사이의 미묘한 차이 것입니다 같은 일을 또는 두 가지 방법을 가지고있는 점은 무엇이다 doReturn(...).when(...)와는 when(...).thenReturn(...)?

도움을 주시면 감사하겠습니다.


1
javadoc에는 doReturn()유용한 몇 가지 경우 가 있습니다.
Sotirios Delimanolis

5
가장 큰 차이점 중 하나는 doReturn (...). when (..)이 더 오래된 유형이고 해당 유형이 안전하지 않기 때문에 컴파일러가 캐스팅에 대해 계속 불평 할 때 사용할 수 있다는 것입니다. . 때 (..) thenReturn (..)는 유형 안전의 측면에서 훨씬 더
user2511882

답변:


227

스터 빙의 두 가지 구문은 거의 같습니다. 그러나, 당신은 할 수 있습니다 항상doReturn/when 스터 빙에 사용할 . 하지만를 사용할 수없는 경우가 있습니다 when/thenReturn. 보이드 방법 스터 빙은 그러한 방법 중 하나입니다. 다른 것에는 Mockito 스파이와 함께 사용하고 같은 방법을 두 번 이상 스터 빙하는 것이 포함됩니다.

한 가지 when/thenReturn 당신을 제공 doReturn/when하지 않는 유형 검사는 컴파일시에, 반환하고 있다는 값이다. 그러나 나는 이것이 거의 가치가 없다고 생각합니다. 유형이 잘못되면 테스트를 실행하는 즉시 알게 될 것입니다.

나는 단지 사용하는 것이 좋습니다 doReturn/when . 두 가지 구문을 배우는 데는 아무런 의미가 없습니다.

밀접하게 관련된 질문에 대한 자세한 답변 인 Forming Mockito "grammars" 에서 내 답변을 참조하십시오 .


16
나는 데이비드와 동의하지 않습니다. 나는 종종 사용할 때 잘못된 유형을 반환 doReturn/when하고 다음 몇 분 동안 무엇이 잘못되었는지 알아내는 상황에 처하게됩니다 . 와 함께 컴파일 유형 유형 검사가 매우 유용합니다 when/thenReturn.
Saket

11
Mockito는 when/thenReturn대신에 use를 사용할 것을 권장합니다 doReturn/when.
CodyEngel

2
@CodyEngel 그리고 여기에 대한 답변과 stackoverflow.com/q/11462697 에서 설명한 것 이외의 권장 사항이 없습니다 . 몇 년 전, 나는 현재 Mockito의 수석 개발자로 활동하고있는 Brice Dutheil과이 문제에 대해 토론했으며, 내 기억에 최선을 다한다고 그는 동의한다. 나는 그에게 의견을 게시하도록 요청할 것입니다 (그가 그렇게 할 것이라는 보장은 없습니다).
다우드 이븐 카림

18
의 javadoc 상태 doReturn/when트레이드 오프입니다. 팀은 어떤 식 으로든 다른 방법으로 명령하지 않지만 when/then접근 방식 이보다 직관적이고 읽기 쉽고 컴파일 시간 검사를 제공한다는 점에 주목하십시오 .Mockito가 인기 있고 사용하기 쉬운 접근 방식이므로 코드베이스를 공유 할 때 잊지 마십시오. 팀의 다양한 스킬 셋; 그러나 스파이와 공극 방법에 관한 단점이 있습니다.
Brice

5
레코드의 경우 : YODA 스타일의 메소드 호출로 변환 doReturn()하는 데 단점이 있습니다. 나중에 문제가 먼저 기록됩니다. 대부분의 사람들은 왼쪽에서 오른쪽으로 읽습니다. 따라서 이제는 헤드의 논리를 되돌릴 때를 항상 기억해야합니다.
GhostCat

199

@Spymock 대신으로 spied 객체 ()로 주석을 달면 두 방식이 다르게 동작합니다 @Mock.

  • when(...) thenReturn(...) 지정된 값이 리턴되기 직전에 실제 메소드 호출 을 작성합니다. 따라서 호출 된 메소드가 예외를 던지면 처리하거나 조롱해야합니다. 물론 여전히 결과를 얻습니다 (당신이 정의 한 것 thenReturn(...))

  • doReturn(...) when(...) 메소드를 전혀 호출하지 않습니다 .

예:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

테스트:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

37
이 동작은 실제 개체의 "래퍼"이므로 스파이 된 개체에 대해서만 작동합니다. 조롱 된 객체의 경우 언제 / thenReturn 또는 doReturn / 언제인지는 중요하지 않습니다. 조롱 된 객체는 실제 메서드를 호출하지 않습니다.
Rafael Orágio

이 기능을 사용해야하는 이유를 더 자세히 설명해 주시겠습니까? 실제 사용 사례가 보이지 않습니다. 테스트의 목적은 다른 사용 사례에서 코드의 정확성을 확인하는 것입니다. 메소드의 calll이 예외 테스트를 던지면 예외를 throw해야합니다. 값을 반환하지 마십시오
Gleichmut

@Gleichmut 이것은 가상 시나리오로 doReturn의 사용법 / 장점을 보여줍니다. 실제 응용 프로그램에서 예외를 반환하는 메서드는 물론 의미가 없습니다. 그러나 특정 조건에서 예외를 throw 할 수있는 메서드 (아마도 이와 같이 얇지는 않음)가 있습니다.
akcasoy

1
설명을 위해 : when (). thenReturn ()-방법은 스파이의 실제 메소드를 한 번만 호출합니다 (모의는 중요하지 않습니다). 이것은 모의 동작을 지정하는 줄에서 발생합니다 (( myClass.anotherMethodInClass () .thenRet ...). 실제 메소드는 다시 호출되지 않습니다. 설명을 읽을 때 데코레이터 논리가 필요한지 아는 것이 좋습니다. 위.
조나스

이것은의 장점처럼 보이지 않으며 doReturn()라이브러리를 남용하는 것처럼 보입니다. 순수한 조롱 대신 스파이의 요점은 실제 전화를 이용하는 것입니다. 그들은 또한이 같은 스파이 사용에 대해 경고 : github.com/mockito/mockito/wiki/Using-Spies-(and-Fakes)을 (그리고 클래스를 확장하고 메서드를 재정의하는 것이 좋습니다 대신)
마태 복음 읽기

13

Mockito javadoc은 Mockito.when (Object)를 사용할 수없는 드문 경우에 doReturn () doReturn()대신에 왜 when()doReturn () 을 사용 하는지 설명하는 것 같습니다 .

Mockito.when (Object)는 항상 유형 호출이 안전하고 더 읽기 쉬운 (특히 연속 호출을 스텁 할 때) 스텁에 권장됩니다.

doReturn ()이 유용한 드문 경우는 다음과 같습니다.

1. 스파이에서 실제 물체를 감시하고 실제 방법을 호출 할 때 부작용이 발생하는 경우

List list = new LinkedList(); List spy = spy(list);

// 불가능 : 실제 메소드가 호출되어 spy.get (0)이 IndexOutOfBoundsException을 던짐 (목록이 비어 있음)

when(spy.get(0)).thenReturn("foo");

// 스터 빙에는 doReturn ()을 사용해야합니다. doReturn("foo").when(spy).get(0);

2. 이전 예외 스터 빙 무시 :

when(mock.foo()).thenThrow(new RuntimeException());

// 불가능 : 예외 스텁 foo () 메소드가 호출되어 RuntimeException이 발생합니다. when(mock.foo()).thenReturn("bar");

// 스터 빙에는 doReturn ()을 사용해야합니다.

doReturn("bar").when(mock).foo(); 위의 시나리오는 Mockito의 우아한 구문의 균형을 보여줍니다. 그러나 시나리오는 매우 드 that니다. 감시는 산발적이어야하며 예외 스터 빙을 무시하는 것은 매우 드 rare니다. 일반적으로 스터 빙을 오버 라이딩하는 것은 너무 많은 스터 빙을 나타내는 잠재적 코드 냄새입니다.


6

이 대답을 계속 하면 , 처음 호출 할 때와 두 번째 호출 할 때와 같이 메소드가 다른 값을 반환하도록하려면 값을 전달할 수 있다는 또 다른 차이점이 있습니다.

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

따라서 동일한 테스트 사례에서 메소드가 호출되면 false를 반환 한 다음 다시 false를 반환하고 마지막으로 true를 반환합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.