Java Mock ClassLoader.getSystemClassLoader().loadClass与Powermockito
我正在尝试测试一个实用方法,该方法检查特定类是否在类路径上,如果是Java Mock ClassLoader.getSystemClassLoader().loadClass与Powermockito,java,unit-testing,powermockito,Java,Unit Testing,Powermockito,我正在尝试测试一个实用方法,该方法检查特定类是否在类路径上,如果是返回trueelse返回false 我这样做的原因:我必须创建扩展同一个类的独立类,并且其中只有一个在类路径上。如果类路径上有一个特定的对象,则需要执行特定的操作 使用下面的方法检查特定类是否在类路径上。 此检查仅在第一次请求后执行一次。 我也检查了Class.forName(),但决定采用下面的方法 我的实用方法如下所示: public static boolean isMyClassOnClassPath() { tr
返回true
else返回false
我这样做的原因:我必须创建扩展同一个类的独立类,并且其中只有一个在类路径上。如果类路径上有一个特定的对象,则需要执行特定的操作
使用下面的方法检查特定类是否在类路径上。
此检查仅在第一次请求后执行一次。
我也检查了Class.forName()
,但决定采用下面的方法
我的实用方法如下所示:
public static boolean isMyClassOnClassPath() {
try {
ClassLoader.getSystemClassLoader().loadClass("com.MyClass");
return true;
} catch (ClassNotFoundException ex) {
return false;
}
}
检查false
条件很容易,因为特定类不是类路径。
我正试图为正面场景编写Junit
,此时此方法将返回true
@Test
public void isMyClassOnClassPathShouldReturnTrueWhenMyClassIsOnClassPath() throws Exception{
PowerMockito.mockStatic(MyClass.class);
ClassLoader classLoader = PowerMockito.mock(ClassLoader.class);
PowerMockito.mockStatic(ClassLoader.class);
PowerMockito.when(ClassLoader.getSystemClassLoader()).thenReturn(classLoader);
//trying to mock classLoader.loadClass, below way is incorrect
//PowerMockito.when(classLoader.loadClass("com.MyClass")).thenReturn(Class<java.lang.Object.class>);
Assert.assertTrue(MyClassUtil.isMyClassOnClassPath());
}
@测试
当CyclassionClassPath()引发异常时,public void IsCyclassonClassPath应返回True{
mockStatic(MyClass.class);
ClassLoader ClassLoader=PowerMockito.mock(ClassLoader.class);
mockStatic(ClassLoader.class);
当(ClassLoader.getSystemClassLoader())。然后返回(ClassLoader);
//试图模拟classLoader.loadClass,下面的方式不正确
//PowerMockito.when(classLoader.loadClass(“com.MyClass”))。然后返回(Class);
Assert.assertTrue(MyClassUtil.isMyClassOnClassPath());
}
那么,可以模拟
classLoader.loadClass()
方法吗 老实说:不要想做那样的事
简言之,你就像一个坐在树上的人,开始随意切割他所坐的树的枝干。意思:这是JVM的核心部分。假设您的模拟可以工作:然后该方法的每个调用方都将收到您的模拟加载程序!所以,当您的测试用例本身想要加载一些类时,它会运行到您的模拟中
和往常一样,当人们声称“我需要为xyz使用Powermock”时,你真正的问题就不同了:你创建了不稳定的代码。通过在那里进行静态调用,您可以阻止自己测试代码
对于初学者,您可以看看如何编写可测试代码。但如果您想知道如何修复您的设计:
class ClassPathChecker {
private final ClassLoader classLoader;
ClassPathChecker() { this(ClassLoader.getSystemClassLoader()); }
ClassPathChecker(ClassLoader classLoader) {
this.classLoader = this.classLoader);
}
boolean canClassBeLoaded(String className) {
try {
classLoader.loadClass ...
上面使用依赖注入插入一个模拟的类加载器;这让你可以完全控制正在发生的一切。根本不使用Powermock
出于好奇:你为什么把自己限制在系统类加载器上?像
Class.forName(“yourclass”)
这样的简单调用不会告诉你同样的情况吗 是的,这似乎是更好的方法。谢谢:)。关于Class.forname(),我已经更新了这个问题。