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

如何用Mockito模拟返回非空HttpsURLConnection的静态方法?

解决Mockito/PowerMockito模拟静态HTTP连接返回null的问题

针对你遇到的静态方法模拟返回null导致空指针的问题,下面给出两种可行的解决方案,分别基于Mockito-inline(Mockito 3.4+支持静态方法模拟)和PowerMockito:

一、使用Mockito-inline实现模拟

1. 依赖配置(Maven示例)

确保引入正确版本的Mockito-inline和JUnit 5依赖:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>

2. 测试用例实现

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class YourToolClassTest {

    @Mock
    private HttpURLConnection mockConnection; // 模拟的连接对象

    @Test
    void testYourToolMethod() throws Exception {
        // 初始化sslURLDetails
        Map<String, String> sslURLDetails = new LinkedHashMap<>();
        sslURLDetails.put("MPOWER_SSL_RTCS_URL1", "https://");
        sslURLDetails.put("SSL_KEY_STORE_FILENAME", "C:/Users/Desktop/certs/XYZ/report.jks");
        sslURLDetails.put("SSL_TRUST_STORE_FILE_NAME", "C:/Users/Desktop/certs/XYZ/report.jks");
        sslURLDetails.put("SSL_USER_PASSCODE", "");
        sslURLDetails.put("SSL_KEY_STORE_TYPE", "JKS");
        sslURLDetails.put("SSL_URL_ENABLED", "true");

        // 模拟HttpsURLServiceUtil的静态方法
        try (MockedStatic<HttpsURLServiceUtil> mockedStatic = mockStatic(HttpsURLServiceUtil.class)) {
            mockedStatic.when(() -> HttpsURLServiceUtil.openHttpURLConnection(sslURLDetails))
                    .thenReturn(mockConnection);

            // 如果工具类中用到URL.openConnection(),同步模拟
            URL mockUrl = new URL("https://example.com");
            try (MockedStatic<URL> urlMockedStatic = mockStatic(URL.class)) {
                urlMockedStatic.when(() -> new URL(any(String.class))).thenReturn(mockUrl);
                when(mockUrl.openConnection()).thenReturn(mockConnection);

                // 调用你的工具类方法
                YourToolClass.yourMethod(sslURLDetails);

                // 可添加验证逻辑,比如确认setRequestMethod被调用
                // verify(mockConnection).setRequestMethod("POST");
            }
        }
    }
}

二、使用PowerMockito实现模拟

1. 依赖配置(Maven示例)

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>

2. 测试用例实现

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest({HttpsURLServiceUtil.class, URL.class}) // 指定要模拟的静态类
public class YourToolClassTest {

    @Mock
    private HttpURLConnection mockConnection;

    @Test
    void testYourToolMethod() throws Exception {
        // 初始化sslURLDetails
        Map<String, String> sslURLDetails = new LinkedHashMap<>();
        sslURLDetails.put("MPOWER_SSL_RTCS_URL1", "https://");
        sslURLDetails.put("SSL_KEY_STORE_FILENAME", "C:/Users/Desktop/certs/XYZ/report.jks");
        sslURLDetails.put("SSL_TRUST_STORE_FILE_NAME", "C:/Users/Desktop/certs/XYZ/report.jks");
        sslURLDetails.put("SSL_USER_PASSCODE", "");
        sslURLDetails.put("SSL_KEY_STORE_TYPE", "JKS");
        sslURLDetails.put("SSL_URL_ENABLED", "true");

        // 模拟HttpsURLServiceUtil静态方法
        PowerMockito.mockStatic(HttpsURLServiceUtil.class);
        when(HttpsURLServiceUtil.openHttpURLConnection(sslURLDetails))
                .thenReturn(mockConnection);

        // 模拟URL类的构造和openConnection方法
        URL mockUrl = PowerMockito.mock(URL.class);
        PowerMockito.whenNew(URL.class).withArguments(any(String.class)).thenReturn(mockUrl);
        when(mockUrl.openConnection()).thenReturn(mockConnection);

        // 调用工具类方法
        YourToolClass.yourMethod(sslURLDetails);

        // 验证逻辑示例
        // PowerMockito.verifyStatic(HttpsURLServiceUtil.class);
        // HttpsURLServiceUtil.openHttpURLConnection(sslURLDetails);
    }
}

关键注意事项

  • 参数匹配要准确:如果需要匹配特定的sslURLDetails,用eq(sslURLDetails);不关心具体参数时,用any(Map.class)即可。
  • Mockito-inline必须用MockedStatic的try-with-resources语法,确保静态模拟的生命周期正确管理。
  • PowerMockito必须通过@PrepareForTest注解指定所有需要模拟的静态类,否则静态方法模拟会失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 20:15:42