You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit5结合Mockito实现Thread.sleep()调用时抛出InterruptedException

如何Mock Thread.sleep()抛出InterruptedException(JUnit5+Mockito)

Thread.sleep()本身的执行逻辑是:如果当前线程持有中断标记,方法会立刻抛出InterruptedException,同时清除中断标记。基于这个特性,你完全不需要做静态Mock,用最轻量化的方式就能覆盖异常分支,这也是优先推荐的方案。


方案1:无需Mock,利用线程原生中断机制(推荐)

直接在调用被测方法前,给当前执行测试的线程设置中断标记即可,Thread.sleep(3000)会自然抛出异常进入catch分支,代码如下:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class SomeClassTest {
    private final SomeClass underTest = new SomeClass();

    @Test
    void shouldReturnHelloWhenSleepInterrupted() {
        // 给当前线程打中断标记
        Thread.currentThread().interrupt();
        
        // 调用被测方法,sleep会自动抛出InterruptedException并被内部catch
        String result = underTest.myMethod();
        
        // 验证方法正常返回结果
        assertEquals("Hello", result);
    }
}

这个方案没有任何Mock框架的兼容性问题,执行效率高,完全模拟真实场景下的中断逻辑。因为sleep抛出异常时会自动清除线程中断标记,不会对其他测试用例造成污染。


方案2:使用Mockito静态Mock能力(适合需要精确验证调用逻辑的场景)

如果你需要精确校验Thread.sleep()的调用次数、传入参数,或者你的逻辑中sleep前有其他会清除中断标记的操作,可以用Mockito 3.4+版本内置的静态方法Mock能力实现,不需要引入PowerMock。
注意Thread.sleep是静态native方法,常规的Mockito实例Mock逻辑对其无效。
测试代码如下:

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.mockito.Mockito.mockStatic;
import static org.junit.jupiter.api.Assertions.assertEquals;

class SomeClassTest {
    private final SomeClass underTest = new SomeClass();

    @Test
    void shouldReturnHelloWhenSleepInterruptedByMock() {
        // 用try-with-resources管理静态Mock生命周期,自动关闭避免跨用例污染
        try (MockedStatic<Thread> threadMock = mockStatic(Thread.class)) {
            // 定义匹配规则:当传入3000调用sleep时抛出异常
            // 如果要匹配所有sleep调用,可以把参数换成anyLong()
            threadMock.when(() -> Thread.sleep(3000L))
                    .thenThrow(new InterruptedException("mock interrupted"));

            String result = underTest.myMethod();

            assertEquals("Hello", result);
            // 可选:校验sleep方法确实被调用了1次
            threadMock.verify(() -> Thread.sleep(3000L));
        }
    }
}

注意事项

  • 必须使用Mockito 3.4.0及以上版本,低版本不支持原生静态Mock。
  • 静态Mock必须放在try-with-resources块中执行,不要把MockedStatic实例定义为类级别的共享变量,否则会污染其他测试用例的执行逻辑。
  • 参数匹配时注意Thread.sleep接收的是long类型参数,不要直接传入int值做精确匹配,会导致匹配规则失效。

内容的提问来源于stack exchange,提问作者user19486104

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:15:53