如何用Mockito模拟TimeUnit.MILLISECONDS.sleep()抛出InterruptedException
解决Mockito模拟TimeUnit.MILLISECONDS.sleep抛出InterruptedException的问题
你需要直接针对TimeUnit.MILLISECONDS这个枚举常量的sleep方法进行静态Stub,而不是创建无关的TimeUnit mock实例。以下是可行的测试代码:
import org.junit.jupiter.api.Test; import org.mockito.Mockito; import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.anyLong; class YourTestClass { @Test void testSleepThrowsInterruptedException() { // 静态mock TimeUnit类,作用域在try-with-resources块内 try (var staticMock = Mockito.mockStatic(TimeUnit.class)) { // 针对MILLISECONDS常量的sleep方法设置抛出异常 staticMock.when(() -> TimeUnit.MILLISECONDS.sleep(anyLong())) .thenThrow(new InterruptedException()); // 实例化被测试类并调用方法 YourClass underTest = new YourClass(); int result = underTest.test(); // 验证返回值是否为1 assertEquals(1, result); } } } // 被测试类示例 class YourClass { public int test(){ try { var test = TimeUnit.MILLISECONDS; test.sleep(500L); } catch (Exception e) { return 1; } return 0; } }
你之前的两种方式失败的原因:
- 第一种方式:你创建的
mock是一个全新的TimeUnit实例,和代码中实际使用的TimeUnit.MILLISECONDS枚举常量没有任何关联,Stub的是这个mock实例的方法,自然不会影响到真实代码中的调用。 - 第二种方式:尝试通过mock
TimeUnit.values()返回自定义mock实例,但TimeUnit.MILLISECONDS是类加载时就初始化的枚举常量,代码中直接引用该常量,不会通过values()方法获取实例,所以这种替换完全无效。
由于TimeUnit是枚举类型,其常量实例是固定的,必须直接针对TimeUnit.MILLISECONDS这个特定实例的sleep方法进行静态mock,才能让代码中的调用抛出异常。
内容的提问来源于stack exchange,提问作者Triterium
相关产品推荐
相关产品推荐

