2014-07-07 1 views
2

나는 다음과 같이 내 모의 스텁하려고 내가 두 번째 스텁 첫 번째를 덮어되는 것으로 나타났습니다Mockito.when 스텁은

when(someMock.someMethod(Matchers.<SomeInterface<Map<String,Boolean>>> any()).thenReturn(someOtherValue); 

when(someMock.someMethod(Matchers.<SomeInterface<MyType>> any()).thenReturn(someValue); 

과, 덮어 쓰기. 따라서 전화 할 때도 someOtherValue이됩니다. someMock.someMethod(new SomeInterfaceImplementation());

여기에 무엇이 누락되어 있는지 잘 모르겠습니다. 이 특정 사용 사례에 대한 Mockito 문서를 살펴 보았지만 아무 것도 찾지 못했습니다.

도움/의견을 보내 주시면 감사하겠습니다.

답변

3

지우기 유형 때문에 Mockito는 someMock.someMethod에 전달되는 SomeInterface<T> 인스턴스의 일반 매개 변수를 런타임에 확인할 수 없습니다. someMethod에 대한 모든 호출은 일반 매개 변수없이 SomeInterface의 인스턴스로 작성된 것으로 보입니다.

(는 이유는 설명하지 않지만) Matchers를위한 JavaDoc는 경고와 함께이 문제를 암시 :

을 방법은 모든 종류의 검사하지 않는, 사람들은 여기있는 모든 가족 귀하의 코드에서 캐스팅을 피하십시오. 유형 검사를 수행하려면 isA (Class) 메소드를 사용하십시오. 그러나 향후 주요 릴리스에서이 유형이 변경 될 수 있습니다 (유형 점검이 추가 될 수 있음).

이 컬렉션의 일반 매개 변수를 처리하는 것 anyListOf 같은 다른 헬퍼 방법은, 그러나 다시이 단지 편의를 위해 존재하고, 실제로 제네릭 형식 확인하지 않습니다 : 친화적 인

일반을 anyList()에 대한 별명. @SuppressWarnings ("unchecked") 대신 컴파일러 경고 코드에서 코드를 깨끗하게 유지할 수 있습니다.

모든 목록 또는 null.

이 방법 은 어떤 종류의 검사도하지 않으므로, 코드에 캐스팅하지 않는 것이 좋습니다. 그러나 향후 주요 릴리스에서이 유형이 변경 될 수 있습니다 (유형 점검이 추가 될 수 있음). any() 정규 관계없이 유형 및 일반 매개 변수의 객체를 일치하기 때문에

, any()when()에 두 번째 호출은 첫 번째보다 우선합니다. 이 문제에 대한 유일한 해결책은 호출 유형 모두에 대해 when(...)을 한 번만 호출하고 어떤 종류의 런타임 검사를 수행하여 결과가 무엇인지 결정하는 것입니다 (예 : AnswerthenAnswer으로 전달 된 경우).

예를 들어, 우리는 다음 클래스 조롱 할 생각 (조롱 정말 가치가 없다, 그러나 나와 함께 곰) :

public class SomeClass { 
    public <T> T getFirst(List<T> list) { 
     return list.get(0); 
    } 
} 

getFirst 방법은 클래스와 같은 문제가, any을 사용하는 등/isA/anyList/anyListOf 정규 표현식 List<String>List<Integer>을 구분할 수 없습니다. 여기

andAnswer 이것을 조롱 한 가지 방법입니다 :

@Test 
public void testGetFirst() { 
    SomeClass mock = mock(SomeClass.class); 

    when(mock.getFirst(Matchers.<List<?>>any())).thenAnswer(new Answer<Object>() { 
     @Override 
     public Object answer(InvocationOnMock invocation) { 
      List<?> list = (List<?>) invocation.getArguments()[0]; 

      // Inspect the contents of the list to know which type to return 
      Object first = list.get(0); 
      if (first instanceof String) { 
       return "Z"; 
      } else if (first instanceof Integer) { 
       return 1000; 
      } else { 
       return null; 
      } 
     } 
    }); 

    String firstString = mock.getFirst(Arrays.asList("A", "B", "C")); 
    System.out.println(firstString); // prints Z 

    Integer firstInteger = mock.getFirst(Arrays.asList(1, 2, 3)); 
    System.out.println(firstInteger); // prints 1000 
} 

이 꽤 못생긴, 그리고 그것을 실제 일반적인 유형의 사용 방법에 따라 달성하기 매우 어려울 수 있지만, 나는 그것이 믿는다 런타임시 제네릭 형식 정보의 부족을 해결할 수있는 유일한 방법입니다.

관련 문제