want to write an unittest for a method like
public static void startProgram() {
process = Runtime.getRuntime().exec(command, null, file);
}
I don't want to inject the runtime object for some reasons, so I wanted to stub the getRuntime method that it returns a Runtime mock... I tried it this way:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Runtime.class)
public class ProgramTest {
@Test
public void testStartProgram() {
Runtime mockedRuntime = PowerMockito.mock(Runtime.class);
PowerMockito.mockStatic(Runtime.class);
Mockito.when(Runtime.getRuntime()).thenReturn(mockedRuntime);
... //test
}
}
But this doesn't work. Actually nothing seems to be mocked. In the test the normal Runtime object is used.
Anyone any idea why this doesn't work and/or how it works?
As this mini example seems not to reproduce the problem here is the full test code: method to test (shortened)
public static synchronized long startProgram(String workspace) {
// Here happens someting with Settings which is mocked properly
File file = new File(workspace);
try {
process = Runtime.getRuntime().exec(command, null, file);
} catch (IOException e) {
throw e;
}
return 0L;
}
and the test:
@Test
public void testStartProgram() {
PowerMockito.mockStatic(Settings.class);
Mockito.when(Settings.get("timeout")).thenReturn("42");
Runtime mockedRuntime = Mockito.mock(Runtime.class);
// Runtime mockedRuntime = PowerMockito.mock(Runtime.class); - no difference
Process mockedProcess = Mockito.mock(Process.class);
Mockito.when(mockedRuntime.exec(Mockito.any(String[].class), Mockito.any(String[].class),
Mockito.any(File.class))).thenReturn(mockedProcess);
PowerMockito.mockStatic(Runtime.class);
Mockito.when(Runtime.getRuntime()).thenReturn(mockedRuntime);
startProgram("doesnt matter");
}
Then, in the test, the call to Runtime.getRuntime() doesn't bring the mock and that's why an IOException is thrown because the String is no directory...
To create an example using PowerMock, we need to go through the following steps. Step 1: Add the following PowerMock dependencies in pom.xml file. To use PowerMock with Mockito, we need to apply the following two annotations in the test: @RunWith (PowerMockRunner.class): It is the same as we have used in our previous examples.
The PowerMockito provides the functionality to work with the Java reflection API. Let's understand the concept of PowerMock with the help of an example. Here, we are going to create an example of PowerMock with Mockito and JUnit frameworks.
Overview. This is where the PowerMock framework comes into play. PowerMockito is a PowerMock’s extension API to support Mockito. It provides capabilities to work with the Java Reflection API in a simple way to overcome the problems of Mockito, such as the lack of ability to mock final, static or private methods.
We use the annotation @Mock on the class instance which we need to test and we test various conditions using the Mockito methods like verify (),when (), doThrow () etc. While Mockito can help with test case writing, there are certain things it cannot do like mocking or testing private, final or static methods.
My bad in the comments, apologies, I had an inner class for the test and that's why I had no trouble. I then realized this and saw your @PrepareForTest(Runtime.class)
which should read @PrepareForTest(MyClass.class)
(replace MyClass with whatever name you have) because Runtime
is a system class. You can read more about this here and find more examples here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With