我在Java中有以下指令:
String path = MyClass.class.getClassLoader().getResource(fileName).getPath();
我需要使用Mockito和Powermock模拟ClassLoader
返回的MyClass.class.getClassLoader()
。
我试过这个:
@Mock ClassLoader classLoader;
whenNew(ClassLoader.class).withAnyArguments().thenReturn(classLoader);
但它没有用。
有人知道怎么做吗?
答案 0 :(得分:2)
正如评论所示:你正在接近这个错误的水平。
查看您的代码:
String path = MyClass.class.getClassLoader().getResource(fileName).getPath();
你看,MyClass.class.getClassLoader().getResource(fileName)
部分;那是"内置"技术
我的意思是:除非您的代码的其他部分混乱使用ClassLoader,否则上面的内容完全按照它应该执行的操作。绝对没有必要进行广泛的测试。你只关心:这里的类和文件名;东西给了我一条路。 那个对你来说很重要。因此:抽象那个!
换句话说:你只需要前进并添加那个额外的抽象,例如:
public interface PathProvider {
public Path getPathFromUrl(Class<?> clazz);
}
一个简单的实现可能看起来像
public class PathProviderImpl implements PathProvider {
@Override
Path getPathFromUrl(Class<?> clazz, String fileName) {
return clazz.getClassLoader().getResource(fileName).getPath();
}
或类似的东西。请注意:您也可以编写一个简单的单元测试来检查此实现。
但核心要点是:不要在生产代码中进行静态调用,而是使用该接口的(模拟)实例。
不需要PowerMock,不需要静态模拟;只是很好,简单的mockito东西!
此外:以上修复您的设计问题。您创建了难以测试的生产代码;并且你不能通过使用大型PowerMock锤来解决这个问题。你修复它改善糟糕的设计。
答案 1 :(得分:0)
您正在嘲笑新的声明,但您的代码中没有任何新的声明
至于我的理解,你应该:
如下:
@Mock ClassLoader classLoader;
PowerMockito.mockStatic(MyClass.class);
BDDMockito.given(MyClass.getClassLoader()).willReturn(classLoader);
PowerMockito.doReturn("desiredResource").when(classLoader).getResource(Mockito.anyString());
此外,您可能需要在测试类的开头设置以下行:
@RunWith(PowerMockRunner.class)
@PowerMockListener(AnnotationEnabler.class)
@PrepareForTest({MyClass.class})
public class yourTestClass....