'How do I mock a static void method (not with doNothing or invocation -> null) using Mockito.mockedStatic?
I have the following classes
class FileDownloader {
public static void downloadFile(String repoUrl, String filename) throws IOException {
// Downloads file from internet
}
}
class FileDownloaderAndProcessor {
public static void downloadAndProcessFile() throws IOException {
//run some processing to figure out what to download
FileDownloader.downloadFile(a, b);
//run various processing on downloaded file
}
}
I used to mock FileDownloader with PowerMockito.doAnswer, where I could basically mock the downloadFiles function by copying a local file from one place to another to simulate the download, then run various tests on the postproccessing
PowerMockito.doAnswer(invocation -> {
//copy from local location x to y depending on arguments
}.when(FileDownloader.class, "downloadFile").etc etc
Due to a recent spring upgrade, we can no longer use powermock and are migrating to MockedStatic. However, I don't see the doAnswer functionality in MockedStatic. I really don't want the tests to require an internet connection to run. How do I mock this void method?
Mockito version: org.mockito:mockito-core:jar:4.0.0 org.mockito:mockito-inline:jar:4.0.0
Solution 1:[1]
You can try when...thenAnswer...
on MockedStatic
provided by Mockito.
try (MockedStatic<FileDownloader> mockedFileDownloader = Mockito.mockStatic(FileDownloader.class)) {
mockedFileDownloader.when(() -> FileDownloader.downloadFile(repoUrl, filename))
.thenAnswer(invocation -> {
// copy from local location x to y depending on arguments
return null;
});
}
Solution 2:[2]
Since all your static classes seem to have only one method you can simply mock the entire class.
Mockito.mockStatic(FileDownloader.class, invocationOnMock -> {
System.out.println("Do Something that simulates the download");
return null;
});
FileDownloader.downloadFile("someRepo", "someFile");
EDIT:
Only mocking a single Method in the class would also be possible with a hacky workaround.
MockedStatic<FileDownloader> your_mocked_call = mockStatic(FileDownloader.class, invoca -> {
if (invoca.getMethod().getName().equals("downloadFile")) {
// custom code here
System.out.println("aaaaaaaaaaaaaaaaaaa");
}
return null;
});
I would however suggest to use the solution provided by Kai-Sheng Yang https://stackoverflow.com/a/72125083/10254476. It is the indended way by mockito. My original simple approach is only simple as long as the entire class can be mocked.
** always remember to call your_mocked_call.close();
otherwise the static mock stays open even after the testClass is finished.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |