Mocking Overloaded Methoods With Mockito [duplicat

2020-04-26 23:36发布

问题:

I am testing some methods that rely on the getForObject() method in the RestTemplate class.

The getForObject() method is overloaded with the signaturesgetForObject(String url, Class<T> responseType, Object... uriVariables) and getForObject(String url, Class<T> responseType, Map<String, ?>

I need to stub the method with Object... in its arguments to throw an exception but I can not because Mockito.any() also encompasses the Map type. Therefore, stubbing the method as getForObject(Mockito.anyString(),Mockito.any(), Mockito.any() will point to BOTH methods triggering a compilation error.

Are there any possible workarounds to this problem?

I have already tried using Mockito.anyObject() to no avail

回答1:

Not sure what your problem might be, but at this point I might as well just post a working example.

As mentioned before you need to properly specify the type of each parameter, so that mockito can locate the matching method signature.

For the syntax to handle varargs used by older mockito versions, check this answer.

import static org.mockito.ArgumentMatchers.any;
...

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    @Test
    public void test() throws Exception {

        RestTemplate api = Mockito.mock(RestTemplate.class);

        Object obj1 = new Object();
        Object obj2 = new Object();
        Object obj3 = new Object();

        Mockito.when(api.getForObject(any(String.class),any(Class.class), ArgumentMatchers.<Object>any())).thenReturn(obj1);
        Mockito.when(api.getForObject(any(String.class),any(Class.class), any(Map.class))).thenReturn(obj2);
        Mockito.when(api.getForObject(any(URI.class),any(Class.class))).thenReturn(obj3);

        Assert.assertEquals(obj1, api.getForObject("", String.class));
        Assert.assertEquals(obj1, api.getForObject("", String.class, obj1));
        Assert.assertEquals(obj1, api.getForObject("", String.class, obj1, obj2));
        Assert.assertEquals(obj1, api.getForObject("", String.class, obj1, obj2, obj3));
        Assert.assertEquals(obj1, api.getForObject("", String.class, new Object[] {obj1,obj2,obj3}));

        Assert.assertEquals(obj2, api.getForObject("", String.class, new HashMap()));

        Assert.assertEquals(obj3, api.getForObject(new URI(""), String.class));
    }
}

For your usecase just replace the thenReturn with thenThrow.



回答2:

Varargs can be represented as an array, so you could try this along with specyfing the exact type of the second param:

getForObject(Mockito.anyString(),Mockito.any(Class.class), Mockito.any(Object[].class))