chcchangchc / powermock

Automatically exported from code.google.com/p/powermock
Apache License 2.0
0 stars 0 forks source link

Problematic mocking of an object with constructor that takes a Class and extra constructor that takes some object #313

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I this a bug or a feature ? It doesn't work as expected or I don't have the 
skills to do the right test ?
(also on StackOverflow as 
http://stackoverflow.com/questions/4959489/how-to-mock-object-with-constructor-t
hat-takes-a-class)

This is the test:

import static junit.framework.Assert.assertTrue;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest( {ClassUnderTesting.class} )
public class ClassUnderTestingTest {

    @Test
    public void shouldInitializeMocks() throws Exception {
        CollaboratorToBeMocked mockedCollaborator = mock(CollaboratorToBeMocked.class);

        whenNew(CollaboratorToBeMocked.class)
            .withArguments(InjectedIntoCollaborator.class)
            .thenReturn(mockedCollaborator);

        new ClassUnderTesting().methodUnderTesting();

        assertTrue(true);
    }
}

These are the classes :

public class ClassUnderTesting {

    public void methodUnderTesting() {
        new CollaboratorToBeMocked(InjectedAsTypeIntoCollaborator.class);
    }

}

public class CollaboratorToBeMocked {

    public CollaboratorToBeMocked(Class<InjectedAsTypeIntoCollaborator> clazz) {
    }

    public CollaboratorToBeMocked(InjectedIntoCollaborator someCollaborator) {
    }

}

public class InjectedAsTypeIntoCollaborator {

}

public class InjectedIntoCollaborator {

}

This is the error :

org.powermock.reflect.exceptions.TooManyConstructorsFoundException: Several 
matching constructors found, please specify the argument parameter types so 
that PowerMock can determine which method you're refering to.
Matching constructors in class CollaboratorToBeMocked were:
CollaboratorToBeMocked( InjectedIntoCollaborator.class )
CollaboratorToBeMocked( java.lang.Class.class )
Here comes the question : how to get make PowerMock figure out what constructor 
to look for ?

The problematic constructors are into CollaboratorToBeMocked. If only the 
constructor that took Class<InjectedAsTypeIntoCollaborator> existed, all would 
be fine.

PS : Also have tried suppresing, but no luck

suppress(constructor(InjectedIntoCollaborator.class));

Original issue reported on code.google.com by Alexandr...@gmail.com on 10 Feb 2011 at 4:22

GoogleCodeExporter commented 9 years ago
the supress is bad. i have also tried with : 
suppress(constructor(CollaboratorToBeMocked.class, 
InjectedIntoCollaborator.class));

Original comment by Alexandr...@gmail.com on 11 Feb 2011 at 8:56

GoogleCodeExporter commented 9 years ago
i took another look at things (my test class was bad). 

updated the whenNew and added the supress. the supress line seems to throw the 
exception

suppress(constructor(CollaboratorToBeMocked.class, 
InjectedIntoCollaborator.class));
whenNew(CollaboratorToBeMocked.class).withArguments(InjectedAsTypeIntoCollaborat
or.class).thenReturn(mockedCollaborator);

Original comment by Alexandr...@gmail.com on 11 Feb 2011 at 9:35

GoogleCodeExporter commented 9 years ago
I haven't tried it but I think that in cases like these you can do:

Constructor  ctor = 
CollaboratorToBeMocked.class.getConstructor(InjectedIntoCollaborator.class);
whenNew(ctor).withArguments(InjectedIntoCollaborator.class).thenReturn(...);

Try and see if that works for you.

Original comment by johan.ha...@gmail.com on 16 Feb 2011 at 7:24