使用Powermockito

时间:2016-09-15 12:20:07

标签: java unit-testing powermockito

我正在尝试测试实用程序方法,检查特定类是否在类路径上,如果是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()方法吗?

1 个答案:

答案 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")之类的简单电话不会告诉你一样吗?