我们可以用PowerMock创建一个java.lang.Class的模拟实例吗?

时间:2015-01-15 13:30:50

标签: java unit-testing powermock

我需要编写一个测试来模拟java.lang.Class类的实例。 这可以通过PowerMock实现吗?

我试着做以下事情:

PowerMock.createMock(Class.class);

结果是:

java.lang.IllegalAccessError: java.lang.Class
    at sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40)
    at org.powermock.reflect.internal.WhiteboxImpl.newInstance(WhiteboxImpl.java:223)
    at org.powermock.reflect.Whitebox.newInstance(Whitebox.java:139)
    at org.powermock.api.easymock.PowerMock.doMock(PowerMock.java:2146)
    at org.powermock.api.easymock.PowerMock.createMock(PowerMock.java:89)

根据PowerMock的文档,这应该是可能的,但我仍然会收到此错误。

有人设法做到这一点吗?

编辑: 我为什么需要这个? 在测试的编码中有以下声明:

if (someObject.getClass().getName().equals(SOME_CLASS_NAME_THAT_I_DONT_HAVE_ACCESS_TO)) { ... do some stuff ... }

我需要我的测试才能在#34;内部进行编码;如果"我甚至不能提供具有相应名称的类的模拟实例。

作为一种解决方法,我可以在测试中创建一个具有相同名称和包的类,但它很难看。

Edit2:

我还尝试了this link

的建议
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Test;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Test1.class})
public class Test1 {

    @Test
    public void test() {
        PowerMock.createMock(Class.class);
    }

}

结果是一样的:" java.lang.IllegalAccessError:java.lang.Class"

所以作为最终结果 - 似乎没有办法创建一个java.lang.Class的模拟实例

谢谢

5 个答案:

答案 0 :(得分:2)

根据这句话,

  

...

     

在java.lang.reflect.Constructor.newInstance(Constructor.java:526)

     

...

PowerMock(使用Objenesis库)尝试实例化java.lang.Class,它只能由JVM实例化。来自docs

  

Class没有公共构造函数。相反,类对象是在加载类时由Java虚拟机自动构造的,并且通过调用类加载器中的defineClass方法来构建。

很快,我几乎可以肯定,手动生成java.lang.Class的实例是不可能的。如果我错了,请纠正我。

顺便说一下,

  

不幸的是我需要更改getClass()。getName()

的返回值

不是嘲笑getClass()方法是你的选择吗?

答案 1 :(得分:2)

您可以使用JavaCompiler动态编译源文件和URLClassLoader来加载类实例。

例如:How do I programmatically compile and instantiate a Java class?

答案 2 :(得分:0)

为什么你在运行时加载课程

Class<?> cls = Class.forName("org.package.Class");

答案 3 :(得分:0)

Class<? extends Collection> clazz = Collection.class;
Constructor c = PowerMockito.mock(Constructor.class);
Collection collection = mock(Collection.class);
    
PowerMockito.mockStatic(clazz);
when(clazz.getDeclaredConstructor(int.class)).thenThrow(NoSuchMethodException.class);
when(clazz.getDeclaredConstructor()).thenReturn(c);
when(c.newInstance()).thenReturn(collection);

verify(clazz).getDeclaredConstructor(int.class);
verify(clazz).getDeclaredConstructor();

答案 4 :(得分:-1)

您确定需要模拟类对象吗? 是否有一个特定原因导致您无法执行以下操作?

public class MyTest {
   public static class TestClass {
       public void doFoo() {}
   }

   @Test
   public void myTest() {
       doStuff(TestClass.class);
   }
}