PowerMock简单实现原理
我们先来看看PowerMock的依赖:
可以看出来,它有两个重要的依赖:javassist和objenesis。
javassist是一个修改java字节码的工具包,objenesis是一个绕过构造方法来实例化一个对象的工具包。由此看来,PowerMock的本质是通过修改字节码来实现对静态和final等方法的mock的。
@RunWith(PowerMockRunner.class)public class TestClassUnderTest { @Test public void testCallArgumentInstance() { showClassLoader("testCallArgumentInstance"); File file = PowerMockito.mock(File.class); ClassUnderTest underTest = new ClassUnderTest(); PowerMockito.when(file.exists()).thenReturn(true); Assert.assertTrue(underTest.callArgumentInstance(file)); } @Test @PrepareForTest(ClassUnderTest.class) public void testCallInternalInstance() throws Exception { showClassLoader("testCallInternalInstance"); File file = PowerMockito.mock(File.class); ClassUnderTest underTest = new ClassUnderTest(); PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file); PowerMockito.when(file.exists()).thenReturn(true); Assert.assertTrue(underTest.callInternalInstance("bbb")); } @Test @PrepareForTest(ClassDependency.class) public void testCallFinalMethod() { showClassLoader("testCallFinalMethod"); ClassDependency depencency = PowerMockito.mock(ClassDependency.class); ClassUnderTest underTest = new ClassUnderTest(); PowerMockito.when(depencency.isAlive()).thenReturn(true); Assert.assertTrue(underTest.callFinalMethod(depencency)); } private void showClassLoader(String methodName) { System.out.println("=============="+methodName+"==============="); System.out.println("TestClassUnderTest: " + TestClassUnderTest.class.getClassLoader()); System.out.println("ClassUnderTest: " + ClassUnderTest.class.getClassLoader()); System.out.println("ClassDependency: " + ClassDependency.class.getClassLoader()); }}