PowerMockito mock a generic constructor

I have a class that is declared like this:

public class GenericFoo<T>
{
    private final Class<T> _c;
    public GenericFoo(Class<T> c)
    {
        this._c = c; 
    }
    /*
    ...
    rest is unimportant
    */
}

I am writing a unit test for a class, call it SomeBar which creates and makes use of instances of GenericFoo. For this test I need the constructor to always return a specific spy of GenericFoo.

    MyWebServiceResponse webServiceResponseObject = setUpTestResponseObject(1,2,3);

    GenericFoo<MyWebServiceResponse> testFoo = PowerMockito.spy(new GenericFoo<MyWebServiceResponse>(MyWebServiceResponse.class));

    PowerMockito.when(testFoo.processResponseObject(webServiceResponseObject))
            .thenAnswer(new Answer<String>()
            {
                @Override
                public String answer(InvocationOnMock invocation) throws Throwable
                {
                    /* details unimportant */
                }
            });

To ensure that testFoo is returned when SomeBar creates an instance of GenericFoo<MyWebServiceResponse>, I've tried this:

PowerMockito.whenNew(com.myCompany.GenericFoo.class)
                .withParameterTypes(MyWebServiceResponse.class)
                .withArguments(MyWebServiceResponse.class)
                .thenReturn(testFoo);

This causes PowerMock to produce the error:

org.powermock.reflect.exceptions.ConstructorNotFoundException: Failed to lookup constructor with parameter types [ com.myCompany.MyWebServiceResponse ] in class com.myCompany.GenericFoo.
...[stack trace snipped]
Caused by: java.lang.NoSuchMethodException: com.myCompany.GenericFoo.(com.myCompany.MyWebServiceResponse)

Is there any way to get a generic constructor to return a specific object in this sort of situation?

Upvotes: 2

Views: 5241

Answers (1)

herman
herman

Reputation: 12305

The root cause of your error is that the parameter type for the constructor is just Class at runtime (and Class<T> at compile time, never MyWebServiceResponse).

So using

.withParameterTypes(Class.class)

should work.

Upvotes: 2

Related Questions