2017-04-07 1 views
2

tl; dr : 형식 매개 변수가 일치하지 않기 때문에 이러한 테스트가 컴파일되지 않습니다. 을 올바르게 컴파일하고 실행하려면 어떻게해야합니까? Mockito, argThat 및 hasEntry

https://github.com/wesleym/matchertest

나는 서비스를 호출 일부 비 - 테스트 코드가 있습니다. 이 메소드는 map 매개 변수를 사용하여 서비스의 activate 메소드를 호출합니다.

public interface Service { 
    public void activate(Map<String, ?> params); 
} 

내가 활성화 Mockito와 서비스 및 검증을 조롱하여이 코드를 테스트하고 싶습니다 :

public class Foo { 
    private final Service service; 

    public Foo(Service service) { 
    this.service = service; 
    } 

    public void bar() { 
    Map<String, ?> params = getParams(); 
    service.activate(params); 
    } 

    private Map<String, ?> getParams() { 
    // something interesting goes here 
    } 
} 

내가 시험에 노력하고있어 일부 코드는 다음과 같은 서비스에 종속 합리적인지도로 불렀습니다. 다음 코드는 작동 :

@Test 
public void testExactMap() { 
    Service mockService = mock(Service.class); 
    Foo foo = new Foo(mockService); 

    foo.bar(); 

    Map<String, String> expectedParams = new HashMap<>(); 
    expectedParams.put("paramName", "paramValue"); 
    verify(service).activate(expectedParams); 
} 

을하지만, 난 그냥지도가 하나의 특정 항목이 포함되어 있는지 테스트하고 싶습니다. Hamcrest hasEntry matcher이 사용 사례에 대한 완벽한 것 같다

@Test 
public void testHasEntry() { 
    Service mockService = mock(Service.class); 
    Foo foo = new Foo(mockService); 

    foo.bar(); 

    verify(mockService).activate(argThat(hasEntry("paramName", "paramValue"))); 
} 

내가 이것을 할 때, 나는하게 IntelliJ IDEA에서 다음과 같은 오류가 발생합니다 :

Error:(31, 45) java: incompatible types: inference variable T has incompatible bounds 
    equality constraints: java.util.Map<? extends java.lang.String,? extends java.lang.String> 
    upper bounds: java.util.Map<java.lang.String,?>,java.lang.Object 
여기서 문제는 내가 Map<String, ?>의 Mockito의 정규 표현을 필요로한다는 것입니다

, 그러나 hasEntry는 Map<? extends String, ? extends String>의 정규 표현식을 제공합니다. 명시 적 형식 매개 변수를 사용하는 경우에도 형식 매개 변수의 "? extends"부분을 조정하기 위해 수행 할 작업을 파악할 수 없습니다. 이 오류를 해결하려면 어떻게해야합니까? 사용해야하는 특정 캐스트 또는 명시 적 유형 매개 변수가 있습니까?

나는 이것을 위해 ArgumentCaptor를 사용할 수 있음을 알고 있습니다. 정말 그럴 수있는 유일한 방법입니까? 햄 크레스 (Hamcrest)의 작업자들과 함께이 작업이 가능합니까?

답변

3

argThat 반환 유형을 어떤 이유로 유추하지 않습니다. 명시 적으로 아래와 같이 주조하십시오 : 아래 그림과 같이

Mockito.verify(foo).bar((Map<String, String>) argThat(Matchers.hasEntry("paramName", "paramValue"))); 

testHasEntryCast() 고정 할 수 있습니다. (Map<String, ?>) 캐스트주의 argThat 반환 형식이다 :

@Test 
public void testHasEntryCast() { 
    Service mockService = mock(Service.class); 
    Foo foo = new Foo(mockService); 

    foo.bar(); 

    verify(mockService).activate((Map<String, ?>) argThat(hasEntry("paramName", "paramValue"))); 
} 
+0

첫째, 잘못된 코드가 니펫을했다. 죄송합니다! 지금 수정되었습니다. 둘째로, 이것은 효과가 없습니다. Service.activate는'Map '을 기대하지만 캐스트에는 와일드 카드가 허용되지 않습니다. '?'를'Object'로 바꾸는 것은 작동하지 않습니다. – Wesley

+0

수입품을 포함한 테스트 코드를 공유 할 수 있습니까? – VinPro

+0

예제 프로젝트에 대한 링크를 질문에 추가했습니다. – Wesley