我试图在单元测试用例中模拟以下函数:
Files.copy(response.getBody(), pathObj, StandardCopyOption.REPLACE_EXISTING);
StandardCopyOption
是java.nio.file
包的枚举:
我试图模仿的方式是:
try {
Mockito.doNothing().when(Files.copy(Mockito.any(InputStream.class), Mockito.any(Path.class), Mockito.any(CopyOption.class)));
}catch (Exception e){
e.printStackTrace();
}
但是我收到以下错误:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 3 recorded:
-> at scheduler.DownloadTest.downloadFile(DownloadTest.java:227)
-> at scheduler.DownloadTest.downloadFile(DownloadTest.java:227)
-> at scheduler.DownloadTest.downloadFile(DownloadTest.java:227)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
答案 0 :(得分:1)
问题在于您正在尝试模拟静态方法。 Mockito不允许这样做。您只能为实际模拟类实例的非静态方法提供行为。
使用时
Mockito.doNothing().when(Files.copy(Mockito.any(InputStream.class), Mockito.any(Path.class), Mockito.any(CopyOption.class)));
在when()方法中,mockito期望对您尝试模拟的类的引用。然后,您需要使用其参数指定方法。
例如:
Mockito.doNothing().when(classInstance).copy(...)
但是,由于此情况下的复制是静态方法,因此上述方法不起作用(在您的代码中,您提供Files.copy的返回值作为类引用)。因此,一种解决方案是使用PowerMock(可以模拟静态方法但与mockito的更高版本不兼容)或将Files类包装在实例包装器中。
例如:
class FilesWrapper {
public long copy(InputStream in, Path target, CopyOption... options) {
return Files.copy(in, target, options);
}
}
现在,将模拟的FilesWrapper实例(Mockito.mock(FilesWrapper.class))注入到您的代码中,并在使用Files.copy的任何地方使用它。由于mockito的默认行为是对模拟类实例的方法不做任何操作,因此您只需要创建模拟。
另一种方法是将Files.copy部分移动到受测试类的受保护方法中。然后可以在测试期间覆盖此受保护的方法。