我有以下方法,我正在尝试使用 Mockito 编写单元测试。我对Mockito相当陌生,并试图赶上。
测试方法
public synchronized String executeReadRequest(String url) throws Exception{
String result = null;
RestClient client = null;
Resource res = null;
logger.debug("Start executing GET request on "+url);
try{
client = getClient();
res = client.resource(url);
result = res.contentType(this.requestType).accept(this.responseType).get(String.class);
}
catch(Exception ioe){
throw new Exception(ioe.getMessage());
}
finally{
res = null;
client = null;
}
logger.info("GET request execution is over with result : "+result);
return result;
}
使用莫米托进行单元测试
@Test
public void testRestHandler() throws Exception {
RestHandler handler = spy(new RestHandler());
RestClient mockClient = Mockito.mock(RestClient.class,Mockito.RETURNS_DEEP_STUBS);
Resource mockResource = Mockito.mock(Resource.class,Mockito.RETURNS_DEEP_STUBS);
doReturn(mockClient).when(handler).getClient();
Mockito.when(mockClient.resource(Mockito.anyString())).thenReturn(mockResource);
//ClassCastException at the below line
Mockito.when(mockResource.contentType(Mockito.anyString()).accept(Mockito.anyString()).get(Mockito.eq(String.class))).thenReturn("dummy read result");
handler.setRequestType(MediaType.APPLICATION_FORM_URLENCODED);
handler.setResponseType(MediaType.APPLICATION_JSON);
handler.executeReadRequest("abc");
}
但是我在网上得到了一个类投射异常
Mockito.when(mockResource.contentType(Mockito.anyString()).accept(Mockito.anyString()).get(Mockito.eq(String.class))).thenReturn("dummy read result");
例外
java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$EnhancerByMockitoWithCGLIB$$4b441c4d cannot be cast to java.lang.String
感谢任何解决此问题的帮助。
非常感谢。
根期间的这种链接方式不正确:
Mockito.when(
mockResource.contentType(Mockito.anyString())
.accept(Mockito.anyString())
.get(Mockito.eq(String.class)))
.thenReturn("dummy read result");
即使您已将模拟设置为返回深存根,匹配器也会通过副作用工作,因此此行无法实现您认为的效果。所有三个匹配器(anyString
、anyString
、eq
(在调用when
时都会被评估,而你的代码可能会在最轻微的挑衅下抛出InvalidUseOfMatchersException
——包括稍后添加不相关的代码或验证。
这意味着你的问题不在于使用eq(String.class)
:而是Mockito试图在不属于它的地方工作类匹配器。
相反,您需要专门存根:
Mockito.when(mockResource.contentType(Mockito.anyString()))
.thenReturn(mockResource);
Mockito.when(mockResource.accept(Mockito.anyString()))
.thenReturn(mockResource);
Mockito.when(mockResource.get(Mockito.eq(String.class))) // or any(Class.class)
.thenReturn("dummy read response");
请注意,这里的一些困难是Apache Wink使用Builder模式,这在Mockito中可能很费力。(我在这里返回了mockResource
,但您可以想象返回特定的其他 Resource 对象,代价是稍后完全按照该顺序要求它们。更好的方法可能是使用默认答案,该答案尽可能返回this
。
通过将 get 调用更改为
get(Mockito.any(Class.class))