如何使用JMockit模拟Thread.sleep()函数?

6
我有以下代码:

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

我该如何使用JMockit测试,以确保当Thread.sleep()抛出InterruptedException时,会调用Thread.currentThread().interrupt()方法?
2个回答

3

这是一个有趣的问题。测试有些棘手,因为模拟java.lang.Thread的某些方法可能会干扰JRE或JMockit本身,并且因为JMockit目前无法动态地模拟诸如sleep之类的本地方法。尽管如此,仍然可以做到:

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();
}

小注释,更新一下,因为现在(jmockit 1.28,但可能从某些版本开始)看起来不同了(取自/受到 JMockit 的 JREMockingTest.java 示例的启发):@Test public void callThreadSleepOnceSomewhere(@Mocked Thread unused) throws Exception { new Expectations() {{ Thread.sleep(anyLong); times = 1; }}; // your code calling Thread.sleep(...) once } - AntiTiming

1

从JMockit 1.43开始,这是不可能的

JMockit 1.43添加了此提交,它检查您是否试图模拟线程并将其列入黑名单。现在您将收到以下异常:

java.lang.IllegalArgumentException: java.lang.Thread不可模拟


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接