在方法(Mockito / PowerMockito)中调用时模拟SomeClass.getClassLoader()

时间:2015-05-08 20:26:57

标签: unit-testing mockito powermock powermockito

我继承了一些未经过测试的代码,并使用以下方法加载资源:

SomeClass.class.getClassLoader().getResource("somefile");

我已经编写了以下测试但与我创建的Mock类加载器有0次交互。任何人都可以评论这种类型的测试是否可行。

public enum SomeClass {

    INSTANCE;

    public boolean someMethod() {
        URL pathToLicense = SomeClass.class.getClassLoader().getResource("somefile"); 
        return false;
    }
}



@Test
public void testLicenseWorkflow(){

    ClassLoader cl = PowerMockito.mock(ClassLoader.class);

    File f = new File("someFile");

    assertTrue(f.exists());

    logger.info(f.getCanonicalPath()  ); 

    when(cl.getResource("somefile")).thenReturn(f.toURL());

    verify(cl).getResource("somefile");

    assertTrue(SomeClass.INSTANCE.someMethod());

}

更新 - 通过类加载器添加资源 我也尝试了下面的内容,但有些方法看起来似乎无效

new URLClassLoader(((URLClassLoader) SomeClass.INSTANCE.getClass().getClassLoader()).getURLs()) {
            @Override
            public void addURL(URL url) {
                super.addURL(url);
                logger.info("Calling add URL");
            }
        }.addURL(f.toURI().toURL());

1 个答案:

答案 0 :(得分:0)

您没有将cl传递给任何人。您为类加载器准备了一个模拟器,然后继续使用另一个类加载器(加载SomeClass的类加载器)加载资源。这就是为什么你的模拟中有0个交互。

关于你的第一个问题,如果你以某种方式将模拟的类加载器传递给实际加载资源的方法,这是可能的。例如,像

public boolean someMethod(Classloader loader) {
  URL pathToLicense = loader.getResource("somefile"); 
  return false;
}

但我不得不说IMO,这个测试不是很有用,你应该嘲笑你自己的组件,而不是java类。如果你的目标是模拟类加载器是在测试时注入不同的文件,更好的方法是更改​​代码以接收Stream并在生产中注入连接到文件的流,并在测试中注入连接到内存中元素的流。

换句话说,当需要在测试时更改资源时,资源会导致不良测试