PowerMock with Spring Dependency Injection

4,707 views
Skip to first unread message

eos

unread,
Feb 16, 2011, 1:43:05 PM2/16/11
to PowerMock
I have a question about integrating PowerMock with Spring dependency
injection. I am currently using Mockito along with Spring to test my
classes. An example would be

RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:**/testContext.xml")
public class ServiceTest {

@Inject
ItemRepository repo;

@Inject
MyService service;

@Test
public void getItems() {
List<String> items = new ArrayList<String>();
items.add("abc");
items.add("def");

when(repo.getItems()).thenReturn(items);

List<String> returnedItems = service.getItemsFromRepo();
assertEquals(2, returnedItems.size());
}
}

The reason I want to use PowerMock is that inside getItemsFromRepo(),
there is now a static method call that I need to mock in addition to
the non-static methods. Obviously Mockito won't support this, but does
PowerMock? I need to have the @RunWith(SpringJUnit4ClassRunner.class)
attribute to support the Spring dependency injection for the non
static method calls, but PowerMock wants me to use the
@RunWith(PowerMockRunner.class) attribute for the static methods. Java
won't allow you to use multiple @RunWith attribute on a single class.
Am I doing this right? If not, what is the way to go about this?

Johan Haleby

unread,
Feb 16, 2011, 1:50:09 PM2/16/11
to powe...@googlegroups.com
Hi,

Great timing for that question :) The latest version of PowerMock supports this using a junit rule. I've blogged about it here. Let us know how it goes (you may need to make use of the @PowerMockIgnore annotation).

/Johan

E S

unread,
Feb 16, 2011, 5:45:24 PM2/16/11
to powe...@googlegroups.com, Johan Haleby
Thanks for the information. I hope this works out. For now I'm getting an error that one of the mocked classes created by mockito can't be found. This seems to happen when you try to mock a class with a static method and another class with an instance method in the same test. I took PowerMockRule the example given in the source code and modified it slightly to demonstrate what I'm talking about. If I take out the mocking of the IdGenerator class (including the PowerMockRule variable) then I don't get the error and the test runs, but of course it doesn't pass because I'm not mocking the static method anymore.

public class IdGenerator {
    public static int generateNewId() {
        return 1;
    }
}

@Component
@Scope("prototype")
public class StringGenerator {
    public String generateString() {
        return "Real bean string ";
    }
}

@Component
@Scope("prototype")
public class MyBean {
    @Inject
    public StringGenerator stringGenerator;
    public String generateMessage() {
        final long id = IdGenerator.generateNewId();
        return stringGenerator.generateString() + id;
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:**/testContext.xml")
@PrepareForTest(IdGenerator.class)
public class SpringExampleTest {
 
    @Rule
    public PowerMockRule rule = new PowerMockRule();
 
    @Inject
    private MyBean myBean;
    
    @Inject
    public StringGenerator stringGenerator;
 
    @Test
    public void mockStaticMethod() throws Exception {
     String s = "Mock string ";
     when(stringGenerator.generateString()).thenReturn(s);
    
        final int id = 99;
        PowerMockito.mockStatic(IdGenerator.class);
        when(IdGenerator.generateNewId()).thenReturn(id);
 
        String message = myBean.generateMessage();
    }
}


Here is the application context configuration:

<bean id="stringGenerator" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="com.test.StringGenerator" />
</bean>


Here is the error message I'm getting:

-------------------------------------------------------------------------------
Test set: com.test.SpringExampleTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.083 sec <<< FAILURE!
mockStaticMethod(com.test.SpringExampleTest)  Time elapsed: 0.078 sec  <<< ERROR!
com.thoughtworks.xstream.converters.ConversionException: javassist.NotFoundException: com.test.StringGenerator$$EnhancerByMockitoWithCGLIB$$54861a3e : javassist.NotFoundException: com.test.StringGenerator$$EnhancerByMockitoWithCGLIB$$54861a3e


---- Debugging information ----

message             : javassist.NotFoundException: com.test.StringGenerator$$EnhancerByMockitoWithCGLIB$$54861a3e
cause-exception     : java.lang.RuntimeException
cause-message       : javassist.NotFoundException: com.test.StringGenerator$$EnhancerByMockitoWithCGLIB$$54861a3e
class               : org.powermock.modules.junit4.rule.PowerMockStatement$1
required-type       : com.test.MyBean
path                : /org.powermock.modules.junit4.rule.PowerMockStatement$1/outer-class/fNext/fTarget/myBean/stringGenerator
line number         : 14
-------------------------------
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:89)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:246)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:218)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:246)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:218)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:246)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:218)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:246)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:218)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:60)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:137)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:33)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:923)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:909)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:853)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:845)
at org.powermock.classloading.DeepCloner.clone(DeepCloner.java:74)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:89)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)
Caused by: java.lang.RuntimeException: javassist.NotFoundException: com.test.StringGenerator$$EnhancerByMockitoWithCGLIB$$54861a3e
at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:188)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:148)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:65)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at com.thoughtworks.xstream.core.util.ClassLoaderReference.loadClass(ClassLoaderReference.java:31)
at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:61)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:71)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:86)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:96)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:52)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.determineType(AbstractReflectionConverter.java:333)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:208)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82)
... 61 more
Caused by: javassist.NotFoundException: com.test.StringGenerator$$EnhancerByMockitoWithCGLIB$$54861a3e
at javassist.ClassPool.get(ClassPool.java:439)
at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:181)
... 91 more


--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To post to this group, send email to powe...@googlegroups.com.
To unsubscribe from this group, send email to powermock+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/powermock?hl=en.

Reply all
Reply to author
Forward
0 new messages