如何通过Mock测试覆盖静态方法InetAddress.getLocalHost()并模拟异常
解决InetAddress.getLocalHost()静态方法的Mock异常测试问题
问题背景
需要Mock Java标准库的静态方法InetAddress.getLocalHost(),模拟其抛出UnknownHostException的场景,以此测试自定义方法getLocalHostName()的异常处理逻辑。
自定义方法实现:
@Override @SneakyThrows public String getLocalHostName() { return InetAddress.getLocalHost().getHostName(); }
原测试用例(存在错误):
@Test void testGetLocalHostThrowsUnknownHostException() throws Exception { mockStatic(InetAddress.class); when(repository.getLocalHostName()).thenThrow(new Exception("exception message")); assertThrows(UnknownHostException.class, InetAddress::getLocalHost); }
运行后报错:
org.mockito.exceptions.base.MockitoException: Checked exception is invalid for this method! Invalid: java.lang.Exception: exception message
错误原因
- 异常类型不匹配:
getLocalHostName()方法使用了@SneakyThrows,该注解会将检查型异常(如UnknownHostException)包装为运行时异常抛出,Mockito不允许为未声明抛出检查型异常的方法指定抛出Exception这类检查型异常。 - 测试逻辑错位:原测试错误地对被测方法
getLocalHostName()设置抛出异常,而实际应该Mock的是依赖的静态方法InetAddress.getLocalHost(),再验证被测方法的行为。
正确的测试实现
import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import java.net.InetAddress; import java.net.UnknownHostException; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mockStatic; @Test void testGetLocalHostThrowsUnknownHostException() { // 静态Mock InetAddress类,用try-with-resources自动清理Mock try (MockedStatic<InetAddress> mockedInetAddress = mockStatic(InetAddress.class)) { // 指定调用getLocalHost()时抛出UnknownHostException mockedInetAddress.when(InetAddress::getLocalHost) .thenThrow(new UnknownHostException("Mocked unknown host")); // 调用被测方法,验证是否抛出运行时异常(@SneakyThrows包装了原始异常) RuntimeException exception = assertThrows(RuntimeException.class, () -> repository.getLocalHostName()); // 可选:验证原始异常类型 // assert exception.getCause() instanceof UnknownHostException; } }
关键说明
- 使用
try-with-resources管理MockedStatic,确保静态Mock在测试结束后自动清理,避免影响其他测试用例。 - 直接对
InetAddress.getLocalHost()设置抛出UnknownHostException,匹配原方法声明的异常类型,符合Mockito的规则。 - 由于
@SneakyThrows的存在,被测方法实际抛出的是运行时异常,断言时需对应RuntimeException;若要验证原始异常类型,可通过异常的getCause()判断。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

