I'm using PowerMock and Mockito to test a Spring controller.
I have the class TestController defined (see below, Snippet #1), and a Unit Test defined for it (see below, Snippet #2). But when I try to unit test it I get an exception (see below, Snippet #3).
If I remove @InjectMocks, remove the TestController instantiation on definition, and do controllerUT = new TestController() in the test function, it works fine (see below, Snippet #4).
This leads me to believe that the static replacement does not happen before @InjectMocks, and my question is if this is the way things work, or am I doing something wrong? Is there a better way to design the code to avoid this issue? I'm guessing people use static log assignment (I did not invent this) so someone must have run into this issue before...
Thanks!
Snippet #1
@Controller @RequestMapping("/api/test") public class TestController { private static final Logger LOG = LoggerFactory.getLogger(TestController.class); @Autowired private GeneralService generalService; @RequestMapping(method=RequestMethod.GET) public void doSomethingUseful( HttpServletRequest request, HttpServletResponse response) { // nothing userful to do right now } }
Snippet #2
@RunWith(PowerMockRunner.class) @PrepareForTest({TestController.class, LoggerFactory.class}) public class TestControllerTest { @InjectMocks private TestController controllerUT = new TestController(); @Mock private GeneralService service; @Mock private Logger loggerMock; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @Before public void setUp() { PowerMockito.mockStatic(LoggerFactory.class); when(LoggerFactory.getLogger(any(Class.class))). thenReturn(loggerMock); } @Test public void doSomethingUsefulTest() { controllerUT.doSomethingUseful(request, response); assert(true); } }
Snippet #3
Failed to auto configure default logger context Reported exception: ch.qos.logback.core.joran.spi.JoranException: Parser configuration error occurred at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:86) at ch.qos.logback.core.joran.event.SaxEventRecorder.recordEvents(SaxEventRecorder.java:57) at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:132) at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:96) at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:55) at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75) at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:148) at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84) at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:54) at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128) at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:108) at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:279) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:252) at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:265) at com.basicservice.controller.TestController.<clinit>(TestController.java:39) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) at javassist.runtime.Desc.getClassObject(Desc.java:43) at javassist.runtime.Desc.getClassType(Desc.java:152) at javassist.runtime.Desc.getType(Desc.java:122) at javassist.runtime.Desc.getType(Desc.java:78) at com.basicservice.controller.TestControllerTest.<init>(TestControllerTest.java:44) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.createTestInstance(PowerMockJUnit44RunnerDelegateImpl.java:188) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.createTest(PowerMockJUnit44RunnerDelegateImpl.java:173) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:195) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:102) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:42) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:128) at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:79) ... 42 more
Snippet #4
@RunWith(PowerMockRunner.class) @PrepareForTest({TestController.class, LoggerFactory.class}) public class TestControllerTest { private TestController controllerUT; @Mock private GeneralService service; @Mock private Logger loggerMock; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @Before public void setUp() { PowerMockito.mockStatic(LoggerFactory.class); when(LoggerFactory.getLogger(any(Class.class))). thenReturn(loggerMock); } @Test public void doSomethingUsefulTest() { controllerUT = new TestController(); controllerUT.doSomethingUseful(request, response); assert(true); } }
--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To view this discussion on the web visit https://groups.google.com/d/msg/powermock/-/KedSroRaWDUJ.
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.
To view this discussion on the web visit https://groups.google.com/d/msg/powermock/-/qZLQDv2A2BoJ.
To view this discussion on the web visit https://groups.google.com/d/msg/powermock/-/uMuQEEgMLKsJ.