在 Java 应用程序中使用 Mockito 模拟 REST 服务中的 HttpUrlConnection 调用时出错

问题描述 投票:0回答:1

我是 Java 的新手。我想使用 Junit 和 Mockito 框架为以下方法编写单元测试。此方法接收负载,建立 http 连接并返回响应:

public static Object callApi(String jsonPayload) throws IOException {
        String serverUrl = "some url";
        URL url = new URL(serverUrl);
        HttpURLConnection http = (HttpURLConnection) url.openConnection();
        http.setRequestMethod("POST");
        http.setDoOutput(true);
        http.setRequestProperty("Accept", "application/json");
        http.setRequestProperty("Content-Type", "application/json");
        byte[] out = jsonPayload.getBytes(StandardCharsets.UTF_8);
        OutputStream stream = http.getOutputStream();
        stream.write(out);
        StringBuilder response = new StringBuilder();

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(http.getInputStream(), StandardCharsets.UTF_8))) {
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            System.out.println(response);
        }
        http.disconnect();
        return response.toString();
    }

我写的单元测试看起来像--

    @Test
    public void testCallApi4() throws Exception {
        // Create a mock HttpURLConnection
        HttpURLConnection connection = mock(HttpURLConnection.class);
        Mockito.doNothing().when(connection).setRequestMethod("POST");
        Mockito.doNothing().when(connection).setDoOutput(true);
        Mockito.doNothing().when(connection).setRequestProperty("Accept", "application/json");
        Mockito.doNothing().when(connection).setRequestProperty("Content-Type", "application/json");
        OutputStream os = mock(OutputStream.class);
        when(connection.getOutputStream()).thenReturn(os);
        InputStream is = new ByteArrayInputStream("{\"result\":\"success\"}".getBytes(StandardCharsets.UTF_8));
        when(connection.getInputStream()).thenReturn(is);

        // Mock the URL and URLConnection
        URL url = mock(URL.class);
        PowerMockito.whenNew(URL.class).withArguments("http://localhost:8080/sdk/caas/v1/").thenReturn(url);
        when(url.openConnection()).thenReturn(connection);

        // Call the method
        String response = (String) ControllerHelper.callApi("{\"data\":\"test\"}");

        // Verify the HttpURLConnection was created with the correct parameters
        verify(url, Mockito.times(1)).openConnection();
        verify(connection, times(1)).setRequestMethod("POST");
        verify(connection, times(1)).setDoOutput(true);
        verify(connection, times(1)).setRequestProperty("Accept", "application/json");
        verify(connection, times(1)).setRequestProperty("Content-Type", "application/json");
        verify(os, times(1)).write("{\"data\":\"test\"}".getBytes(StandardCharsets.UTF_8));

        // Verify the response is correct
        assertEquals("{\"result\":\"success\"}", response);
    }

但不知何故我无法正确地模拟它并得到一个错误--

java.net.ConnectException: Connection refused

    at java.base/sun.nio.ch.Net.connect0(Native Method)
    at java.base/sun.nio.ch.Net.connect(Net.java:579)
    at java.base/sun.nio.ch.Net.connect(Net.java:568)
    at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588)
    at java.base/java.net.Socket.connect(Socket.java:633)
    at java.base/java.net.Socket.connect(Socket.java:583)
    at java.base/sun.net.NetworkClient.doConnect(NetworkClient.java:183)
    at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:498)
    at java.base/sun.net.www.http.HttpClient.openServer(HttpClient.java:603)
    at java.base/sun.net.www.http.HttpClient.<init>(HttpClient.java:246)
    at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:351)
    at java.base/sun.net.www.http.HttpClient.New(HttpClient.java:373)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1309)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1242)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1128)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:1057)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1430)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1401)
    at com.jio.caas.utils.ControllerHelper.callApi(ControllerHelper.java:47)

有人可以告诉我我错过了什么吗?我尝试了几种方法来嘲笑这个。

java junit mockito httpurlconnection powermockito
1个回答
0
投票

您不能使用 Mockito 模拟此调用,因为 URL 是在方法内部创建的,请考虑更改方法签名:

public static Object callApi(String jsonPayload) throws IOException 

public static Object callApi(String jsonPayload,  HttpURLConnection http) throws IOException 

然后你将模拟的

HttpURLConnection
传递给你的方法

© www.soinside.com 2019 - 2024. All rights reserved.