Mockito中的ClassCastException

时间:2016-01-30 07:31:02

标签: java mockito

我有以下方法,我正在尝试使用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;
}

使用Mockito进行单元测试

@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");
}

但是我在

行获得了ClassCastException
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

感谢您解决此问题的任何帮助。

非常感谢。

2 个答案:

答案 0 :(得分:3)

在存根期间这种链接方式是不正确的:

Mockito.when(
    mockResource.contentType(Mockito.anyString())
        .accept(Mockito.anyString())
        .get(Mockito.eq(String.class)))
    .thenReturn("dummy read result");

即使你已经设置了模拟来返回深层存根Matchers work via side-effects,所以这条线并没有达到你的想象。所有三个匹配器(anyStringanyStringeq)都会在调用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,但您可以想象返回特定的其他资源对象,但代价是稍后要求它们完成相同的顺序。)更好的方法可能是use a default Answer that returns this whenever possible。< / p>

答案 1 :(得分:-2)

通过更改对

的get调用解决了这个问题
get(Mockito.any(Class.class))