CorayThan
CorayThan

Reputation: 17825

Can't return Class Object with Mockito

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?

Upvotes: 50

Views: 47794

Answers (6)

Valerij Dobler
Valerij Dobler

Reputation: 2764

Two more solutions:

Here we trade the compilation error for an Unchecked assignment warning:

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

A more concise solution without warnings would be

Class<?> userClass = User.class;
when(methodParameter.getParameterType()).thenAnswer(__ -> userClass);

Upvotes: 0

Dennis Gloss
Dennis Gloss

Reputation: 2841

You can simply remove from Class))

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

Upvotes: 6

noisiveRevision
noisiveRevision

Reputation: 95

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.

Upvotes: 1

fgb
fgb

Reputation: 18569

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);

Upvotes: 32

tasontag
tasontag

Reputation: 1045

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();

Upvotes: 103

Daniel Kaplan
Daniel Kaplan

Reputation: 67360

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;
    }


}

Upvotes: 13

Related Questions