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.