Java+PowerMockito如何替换或Mock Thread.sleep方法
解决PowerMockito Mock Thread.sleep抛异常的方案
你之前的写法未生效的核心原因是缺少系统类静态Mock的必要前置配置,同时静态方法Mock的API用法有误,正确实现步骤如下:
1. 测试类前置配置(必做)
- 测试类上添加
@RunWith(PowerMockRunner.class)注解(JUnit4环境),JUnit5环境替换为@ExtendWith(PowerMockExtension.class) - 添加
@PrepareForTest({调用Thread.sleep的业务类.class})注解,注意不要填写Thread.class:JDK系统类由根类加载器加载,Mock时仅需将调用该静态方法的业务类加入预备测试列表即可 - 可选添加
@PowerMockIgnore({"javax.management.*", "sun.reflect.*"})避免类加载冲突
2. 正确Mock写法
方式1:基于mockStatic的写法
适合需要Mock Thread多个静态方法的场景:
// 先开启Thread类的静态方法Mock PowerMockito.mockStatic(Thread.class); // 匹配所有long入参的sleep调用,抛出自定义异常 PowerMockito.doThrow(new Exception("自定义异常信息")).when(Thread.class); Thread.sleep(Mockito.anyLong()); // 若仅需匹配固定时长的sleep调用,修改为具体参数即可 PowerMockito.doThrow(new Exception("1s休眠调用异常")).when(Thread.class); Thread.sleep(1000L);
方式2:基于replace方法的写法
适合仅需要替换sleep方法、不影响Thread其他方法的场景,侵入性更低:
PowerMockito.replace(PowerMockito.method(Thread.class, "sleep", long.class)) .with((proxy, method, args) -> { throw new Exception("自定义异常信息"); });
3. 常见踩坑说明
- 不要漏写
PowerMockito.mockStatic(Thread.class),静态方法Mock必须先执行该初始化 - doThrow写法中,
Thread.sleep(xxx)必须单独写在when(Thread.class)的下一行,不可写到when的括号内 - 若业务代码中还有Thread类其他方法的调用,优先使用replace方案避免影响其他逻辑
内容的提问来源于stack exchange,提问作者Artanis Zeratul
相关产品推荐
相关产品推荐

