Can't return Class Object with Mockito

2019-04-03 03:11发布

问题:

I'm trying to write a unit test, and to do that I'm writing a when statement for a Mockito mock, but I can't seem to get eclipse to recognize that my return value is valid.

Here's what I'm doing:

Class<?> userClass = User.class;
when(methodParameter.getParameterType()).thenReturn(userClass);

The return type of .getParameterType() is Class<?>, so I don't understand why eclipse says, The method thenReturn(Class<capture#1-of ?>) in the type OngoingStubbing<Class<capture#1-of ?>> is not applicable for the arguments (Class<capture#2-of ?>). It offers to cast my userClass, but that just makes some garbled stuff eclipse says it needs to cast again (and can't cast).

Is this just an issue with Eclipse, or am I doing something wrong?

回答1:

Also, a slightly more terse way to get around this is to use the do syntax instead of when.

doReturn(User.class).when(methodParameter).getParameterType();


回答2:

Class<?> userClass = User.class;
OngoingStubbing<Class<?>> ongoingStubbing = Mockito.when(methodParameter.getParameterType());
ongoingStubbing.thenReturn(userClass);

The OngoingStubbing<Class<?>> returned by Mockito.when is not the same type as ongoingStubbing because each '?' wildcard could be bound to a different type.

To make the types match, you need to specify the type parameter explicitly:

Class<?> userClass = User.class;
Mockito.<Class<?>>when(methodParameter.getParameterType()).thenReturn(userClass);


回答3:

I'm not sure why you're getting this error. It must have something special to do with returning Class<?>. Your code compiles fine if you return Class. This is a simulation of what you're doing and this test passes. I think this will work for you, too:

package com.sandbox;

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import static org.mockito.Mockito.*;

import static junit.framework.Assert.assertEquals;

public class SandboxTest {

    @Test
    public void testQuestionInput() {
        SandboxTest methodParameter = mock(SandboxTest.class);
        final Class<?> userClass = String.class;
        when(methodParameter.getParameterType()).thenAnswer(new Answer<Object>() {
            @Override
            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
                return userClass;
            }
        });

        assertEquals(String.class, methodParameter.getParameterType());
    }

    public Class<?> getParameterType() {
        return null;
    }


}


回答4:

I found the code examples here a little confusing with the use of methodParameter.getParameterType() first used in the accepted answer's SandBoxTest. After I did a little more digging I found another thread pertaining to this issue that provided a better example. This example made it clear the Mockito call I was in need of was doReturn(myExpectedClass).when(myMock).callsMyMethod(withAnyParams). Using that form allows me to mock a return of Class. Hopefully this note will help someone searching on a similar problem in the future.



回答5:

You can simply remove from Class))

Class userClass = User.class;
when(methodParameter.getParameterType()).thenReturn(userClass);