6

I have the following code:

class Sleeper {
    public void sleep(long duration) {
        try {
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

How do I test, with JMockit, that Thread.currentThread().interrupt() is called if Thread.sleep() throws an InterruptedException?

Noel Yap
  • 18,822
  • 21
  • 92
  • 144

2 Answers2

3

Interesting question. A bit tricky to test because mocking certain methods of java.lang.Thread can interfere with the JRE or with JMockit itself, and because JMockit is (currently) unable to dynamically mock native methods such as sleep. That said, it can still be done:

public void testResetInterruptStatusWhenInterrupted() throws Exception
{
    new Expectations() {
       @Mocked({"sleep", "interrupt"}) final Thread unused = null;

       {
           Thread.sleep(anyLong); result = new InterruptedException();
           onInstance(Thread.currentThread()).interrupt();
       }
    };

    new Sleeper.sleep();
}
Rogério
  • 16,171
  • 2
  • 50
  • 63
  • Small comment with an update as it now (jmockit 1.28, but probably starting some versions before) looks different (taken/inspired from/by the JREMockingTest.java sample of JMockit): `@Test public void callThreadSleepOnceSomewhere(@Mocked Thread unused) throws Exception { new Expectations() {{ Thread.sleep(anyLong); times = 1; }}; // your code calling Thread.sleep(...) once }` – AntiTiming Oct 03 '16 at 16:58
1

As of JMockit 1.43, this is impossible

JMockit 1.43 added this commit, which checks if you are trying to mock a thread and blacklists it. Now you will get this exception:

java.lang.IllegalArgumentException: java.lang.Thread is not mockable

Thunderforge
  • 19,637
  • 18
  • 83
  • 130