FAILED CONFIGURATION: @BeforeClass setUp org.mockito.exceptions.base.MockitoException: Unable to initialize @Spy annotated field 'allRequestParams'

I have an application (Spring MVC 4 + Hibernate/JPA + MySQL + Maven integration example using annotations), integrating Spring with Hibernate using annotation based configuration.

I want to test this method of one controller:

 @RequestMapping(value = { "/androidCallBack" }, method = RequestMethod.GET)
    public String performAndroidCallBack(@RequestParam Map<String, String> allRequestParams) throws ClientProtocolException, IOException {
...
}

this is the Test

public class AndroidCallBackControllerTest {

    @InjectMocks
    AndroidCallBackController androidCallBackController;

    @Spy
    Map<String, String> allRequestParams;

    @BeforeClass
    public void setUp(){
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void androidCallBack() throws ClientProtocolException, IOException {

        Assert.assertEquals(androidCallBackController.performAndroidCallBack(allRequestParams), "alldevices");

    }

}

but I have this error when running the test

FAILED CONFIGURATION: @BeforeClass setUp
org.mockito.exceptions.base.MockitoException: Unable to initialize @Spy annotated field 'allRequestParams'.
Type 'Map' is an interface and it cannot be spied on.
    at com.tdk.oti.controller.AndroidCallBackControllerTest.setUp(AndroidCallBackControllerTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

Answers


I think the problem with the declaration below

@Spy
Map<String, String> allRequestParams;

is that it doesn't make sense to 'spy' on a Map. A 'spy' object is created from a 'real' object, and by default calling methods on the spy calls the same methods on the real object. Once you've created the spy, you can change the behaviour of some of the methods on the spy if you wish to. However, as Map is an interface, you've got no real object to start with so Mockito can't create the object the 'spy' will call if a method's behaviour hasn't been changed.

Instead, you could either mock out the map, using

@Mock
Map<String, String> allRequestParams;

or forget about mocks and spies for this collection and just use a HashMap<String, String> instead.

Personally, I'd go for the HashMap approach here. I don't really see the need to mock out classes that are as central to Java as the collections classes. It is safe to assume that they will behave as specified, and it is also quite difficult to write much in the way of Java code without them.


Need Your Help

TempData[] usage in MVC3 controller errs w/The SessionStateTempDataProvider class requires session state to be enabled

asp.net asp.net-mvc-3

I'm trying to use TempData[] in an mvc3 controller and I am running into the following error:

faster code to remove first elements from byte array

c# algorithm bytearray

So I have a byte array, and I need to remove the first 5 elements from it. Anyway, I looked online and I couldn't find anything that suited what I was looking for. So I made this, and it is horribl...