我正在尝试测试实用程序方法,检查特定类是否在类路径上,如果是return true
其他return false
。
为什么我这样做:我必须使用扩展同一个类的独立类,并且只有一个类在classpath上。如果一个特定的类在路径上,则需要做特定的事情。
使用以下方法检查特定类是否在类路径上。
此检查仅在首次请求后进行一次。
我还检查了Class.forName()
,但决定采用以下方法。
我的实用程序方法如下所示:
public static boolean isMyClassOnClassPath() {
try {
ClassLoader.getSystemClassLoader().loadClass("com.MyClass");
return true;
} catch (ClassNotFoundException ex) {
return false;
}
}
检查false
条件很简单,因为特定类不是ClassPath。
当此方法返回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());
}
那么可以模拟classLoader.loadClass()
方法吗?
答案 0 :(得分:3)
老实说:甚至认为关于做那样的事情。
简而言之,你就像坐在树上的人一样,开始切割人所坐的树的随意肢体。含义:这是JVM的核心部分。假设你的模拟工作:那么该方法的每个调用者都会收到你的模拟加载器!所以,当你的测试用例本身想要加载一些类时,它会遇到你的模拟!
和往常一样,当人们声称“我需要为xyz使用Powermock”时,你真正的问题是另一个问题:你创建了不可测试的代码。通过在那里进行静态调用,可以防止自己测试代码!
对于初学者,您可以查看here以了解如何编写可测试代码。但如果您对如何修复设计感到好奇:
class ClassPathChecker {
private final ClassLoader classLoader;
ClassPathChecker() { this(ClassLoader.getSystemClassLoader()); }
ClassPathChecker(ClassLoader classLoader) {
this.classLoader = this.classLoader);
}
boolean canClassBeLoaded(String className) {
try {
classLoader.loadClass ...
以上使用依赖注入来插入模拟 ClassLoader;这使您可以完全控制正在进行的所有操作。不使用Powermock 。
出于好奇:为什么要限制自己使用System类加载器?像Class.forName("yourclass")
之类的简单电话不会告诉你一样吗?