Is it possible to mock Class.class?

5,878 views
Skip to first unread message

Aaron

unread,
Jun 27, 2011, 7:04:17 PM6/27/11
to PowerMock
Hi,

I'm facing a problem with a legacy code that uses the Class.class in
order dynamically create instances of some class. When I try to mock
the Class.class I get an exception because Class.class has a private
constructor.

According with the comments on the Java source code: "Constructor.
Only the Java Virtual Machine creates Class objects."

Version: 1.8.5

Original code under test (simplified version):
public static LegacyClass getClass(){
LegacyClass myClass=null;
Class c = Class.forName("sample.code");
myClass = (LegacyClass)c.newInstance();
myClass.doSomething();
return myClass;
}

Test:
@Test
public void testForLegacyCode() throws Exception {
mockStatic(Class.class);
Class mockClass = PowerMockito.mock(Class.class); // Here is where
the exception is thrown.
when(Class.forName("sample.code")).thenReturn(mockClass);
LegacyClass mockLegacyClass = mock(LegacyClass.class);
when(mockClass.newInstance()).thenReturn(mockLegacyClass);
assertEquals(mockLegacyClass, SomeClass.LegacyClass());
}

Stack Trace:

java.lang.IllegalAccessError: java.lang.Class
at
sun.reflect.GeneratedSerializationConstructorAccessor11.newInstance(Unknown
Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at
org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:
40)
at
org.powermock.reflect.internal.WhiteboxImpl.newInstance(WhiteboxImpl.java:
239)
at org.powermock.reflect.Whitebox.newInstance(Whitebox.java:138)
at
org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:
59)
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
at my.test.code
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.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl
$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:
322)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:
86)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
94)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl
$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:
309)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl
$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:
112)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl
$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:
73)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl
$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:
297)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:
84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:
222)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:
161)
at
org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl
$1.run(PowerMockJUnit44RunnerDelegateImpl.java:135)
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:
133)
at
org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:
112)
at
org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:
57)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:
49)
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)

Johan Haleby

unread,
Jun 28, 2011, 3:25:13 AM6/28/11
to powe...@googlegroups.com
Hi, 

I don't think there's a possibility to mock Class because that will mess up a lot of PowerMock internal stuff. You can how ever mock the "getClass()" method of Objects if you set MockGateway.MOCK_GET_CLASS_METHOD = true. 

I would strongly advice against mocking Class or getClass method though. Try to verify it in some other way. 

/Johan


--
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.


Aaron

unread,
Jun 28, 2011, 3:39:27 PM6/28/11
to PowerMock
Thanks Johan, I was trying to avoid loading the actual class due to
some additional dependencies but I followed your advice and avoided
the mocking of class or getClass.

Regards,
--Aaron.

sivaram....@gmail.com

unread,
Jul 9, 2018, 7:55:55 AM7/9/18
to PowerMock
HI I am facing the same error.
 Class.forName(" class path").newInstance()


how to mock the above code with PowerMock 

Thanks,
Sivaram.

Артур Загретдинов

unread,
Jul 14, 2018, 5:12:46 AM7/14/18
to PowerMock
You might be able to mock the Class.forName(" class path").newInstance() as all other Java System classes. To do it you have to add a class that use a system class to @PrepareForTest. More information you may find here 


Thanks,
Artur
Reply all
Reply to author
Forward
0 new messages