Search code examples
javaunit-testingjmockitexpectations

JMockit mock returns String instead of the List<String> provided


Granted, it's been a while since I used JMockit, but I don't remember this kind of difficulty. I have a very simple test of some very simple code. But even though I set returns = List, the mocked method keeps returning just a String! Here's the test:

public class ResponseWrapperTest {
  @Mocked
  UriInfo uri;

  @Mocked  // I've also tried @Injectable
  MultivaluedMap<String,String> queryParams;

  @Test
  public void ResponseWrapper() throws JSONException {
      final List<String> arSkip = new ArrayList<String>(Arrays.asList("0"));        

      new Expectations() {{
          uri.getQueryParameters();     result = queryParams;
          queryParams.get("skip");      result = arSkip;    
      }};

      ResponseWrapper wrapper = new ResponseWrapper(uri);
}

And here's the code it's testing:

ResponseWrapper(UriInfo uriInfo) {
    MultivaluedMap<String,String> params = uriInfo.getQueryParameters();
    String skip = getParam(params, "skip");
}

private String getParam(MultivaluedMap<String,String> params, String name) {
    String result = null;
    List<String> list = params.get(name);  // <== Cast exception occurs here
    if (list != null) {
        result = list.get(0);
    }   
    return result;
}

Note that "params" is a MultivaluedMap, not a Map. So params.get() is expected to return a List. As you see, I'm setting return to a List yet the mocked get() in the code returns the contained String only and this causes a casting exception.

I've tried using returns(...) as well. I've tried making arSkip in sepearate steps and defining it as final. Nothing works.

I'm suspecting that JMockit is interpreting my list as sequential responses, but it should see that the type matches the method's return type. What is going on here?


Solution

  • It's a regression starting in JMockit 1.11 (Aug/2014). It will be fixed in version 1.20 (Oct/2015).