如何Mock Thread.sleep?Quarkus或Mockito实现方案咨询
如何Mock Thread.sleep()避免测试等待5秒?
当然可以,下面分别给你两种场景下的实用实现方案:
用Mockito Mock静态的Thread.sleep()
因为Thread.sleep()是静态方法,普通Mockito核心库不支持静态Mock,你需要引入mockito-inline依赖(Mockito 3.4版本及以上支持)。
具体代码示例:
import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import static org.mockito.Mockito.mockStatic; public class YourServiceTest { @Test void testRetryWithoutSleep() { // 用try-with-resources自动关闭静态Mock,避免影响其他测试 try (MockedStatic<Thread> mockedThread = mockStatic(Thread.class)) { // 让Thread.sleep(5000)直接返回,不执行等待逻辑 mockedThread.when(() -> Thread.sleep(5000)).thenAnswer(invocation -> null); // 执行你的业务方法测试,此时sleep不会等待5秒 yourService.yourRetryMethod(); } } }
注意:静态Mock尽量只在必要时使用,它会全局替换Thread类的静态方法,可能影响测试类中的其他逻辑,用完一定要及时关闭(上面的try-with-resources会自动处理)。
在Quarkus中更优雅的方案:封装Sleep逻辑为Bean
直接Mock静态方法不是最优雅的做法,Quarkus推荐用依赖注入解耦。你可以把sleep逻辑封装成独立Bean,测试时直接替换这个Bean即可:
- 先封装Sleep服务:
import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class SleepService { public void sleep(long millis) throws InterruptedException { Thread.sleep(millis); } }
- 业务代码中注入这个Bean使用:
import javax.inject.Inject; public class YourRetryService { @Inject SleepService sleepService; public void retryOnException() { try { // 业务逻辑 } catch (Exception e) { try { sleepService.sleep(5000); // 调用封装的sleep方法 } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } // 重试逻辑 } } }
- 测试时用Quarkus的
@InjectMock替换SleepService:
import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.mockito.InjectMock; import org.junit.jupiter.api.Test; import static org.mockito.Mockito.doNothing; @QuarkusTest public class YourRetryServiceTest { @InjectMock SleepService sleepService; @Inject YourRetryService yourRetryService; @Test void testRetryWithoutSleep() { // 让mock的sleepService不执行等待逻辑 doNothing().when(sleepService).sleep(5000); // 执行测试,不会等待5秒 yourRetryService.retryOnException(); } }
这种方式符合Quarkus的依赖注入理念,避免了静态Mock的全局影响,测试逻辑也更清晰。
内容的提问来源于stack exchange,提问作者Toni26
相关产品推荐
相关产品推荐

