Here's my setup which is not working:
SomeclassTest.java
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeclassTest.class, Someclass.class})
public class SomeclassTest{
@InjectMocks
private Someclass someclass;
@Test(expected=None.class)
public void testRun() throws Exception{
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException()).when(Thread.class);
Thread.sleep(Matchers.anyLong());
try {
Thread.sleep(5L);
}catch(Exception ex) {
System.out.println("working"); // this is working
}
WhiteboxImpl.invokeMethod(someclass, "run"); // not working in someclass
PowerMockito.verifyStatic();
}
Someclass.java
@Named("Someclass")
public class Someclass extends Thread{
@Override
public void run() {
while (true) {
try {
// clear interruption
interrupted();
long noOfRec= 0;
if (noOfRec> 0) {
Thread.sleep(shortInterval);
} else {
Thread.sleep(longInterval);
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
}
}
}
My issue is PowerMockito isn't mocking Thread.sleep()
when it's actually called in Someclass
but weirdly working when Thread.sleep()
is called inside the JUnit itself.
I am aware that wrapping Thread.sleep()
in another method will solve my issue but I just want to know the correct method of mocking Thread.sleep()
with PowerMockito.
Thread. sleep is bad! It blocks the current thread and renders it unusable for further work.
Mockito allows us to create mock objects. Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.
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.
Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.
Working example here. Note that this concentrates on "how to mock Thread.sleep
" and does not include all of the original code in your example. (I'm not sure that your example is complete enough to reproduce exactly.)
If the class "under test" looks like this (where we log the elapsed time of Thread.sleep
):
(Edit: note that the empty catch (Exception ex)
block will now log a message).
public class SomeClass extends Thread {
private long shortInterval = 100;
private long longInterval = 5000;
@Override
public void run() {
// original code had `while (true)` but this is simpler as an illustration:
int counter = 0;
while (counter < 3) {
try {
// clear interruption
interrupted();
long noOfRec = 0;
if (noOfRec > 0) {
Thread.sleep(shortInterval);
} else {
// in addition to Thread.sleep, log the elapsed time
long startTime = System.nanoTime();
Thread.sleep(longInterval);
long elapsedInNanos = System.nanoTime() - startTime;
long elapsedInSeconds = TimeUnit.SECONDS.convert(elapsedInNanos, TimeUnit.NANOSECONDS);
System.out.println(String.format("TRACER elapsed in seconds: %d", elapsedInSeconds));
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
System.out.println("TRACER caught exception: " + ex.getMessage());
}
counter++;
}
}
}
then consider the following test:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeClass.class, Thread.class})
public class SomeClassTestCase {
@Test(expected=Test.None.class)
public void testRun() throws Exception {
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException("mock error")).when(Thread.class);
Thread.sleep(Matchers.anyLong());
SomeClass someClass = new SomeClass();
// test
someClass.run();
}
}
Without mocks, the test will take ~15 seconds (since the code will sleep for 5 seconds, three times), but with mocks, the output is:
TRACER caught exception: mock error
TRACER caught exception: mock error
TRACER caught exception: mock error
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