如何在mockito中存根HttpClient发送方法

yqkkidmi  于 2023-03-30  发布在  其他
关注(0)|答案(3)|浏览(175)

我正在使用HttpClient调用外部API,如下所示:

HttpClient client = HttpClient.newHttpClient();
   HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/api"))
                    .POST(BodyPublishers.ofString(requestBody)).header("Authorization", 
                           authorizationHeader)
                    .header("Content-Type", "application/json").build();

   HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
   LOGGER.debug(response.body());

我试过How to mock HttpClient's send method in junit 5?的解决方案。这实际上没有关于如何在stubbing语句中返回预期响应的信息。
我基本上是在寻找下面的语句存根,这样我就可以测试预期和实际的结果,而无需调用真实的的API,

client.send(request, HttpResponse.BodyHandlers.ofString());

真实的的API调用返回String格式的json,然后我将把它Map到实体并进一步使用它。
有人能把你的想法放在这上面吗?提前感谢。

efzxgjgh

efzxgjgh1#

测试的问题在于,由于HttpClient示例是在测试方法内部创建的,因此无法模拟它。
您可能希望扩展测试,对传递给send的参数进行更多Assert,并测试您对响应的处理(这在您的问题中没有显示),但我认为这个答案解释了如何成功地模拟客户端。

package com.example.demo;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

class MyClass {
    private final HttpClientFactory httpClientFactory;

    MyClass(HttpClientFactory httpClientFactory) {
        this.httpClientFactory = httpClientFactory;
    }

    public HttpResponse<String> myMethod(String requestBody) throws IOException, InterruptedException {

        HttpClient client = httpClientFactory.create();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:8080/api"))
                .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                .header("Content-Type", "application/json").build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return response;
    }
}

class HttpClientFactory {
    public HttpClient create() {
        return HttpClient.newHttpClient();
    }
}

public class MyTest {

    @Test
    public void aTest() throws IOException, InterruptedException {
        HttpClientFactory mockFactory = mock(HttpClientFactory.class);
        HttpClient mockClient = mock(HttpClient.class);
        HttpResponse mockResponse = mock(HttpResponse.class);
        when(mockFactory.create()).thenReturn(mockClient);
        when(mockClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class)))
                .thenReturn(mockResponse);
        MyClass classToTest = new MyClass(mockFactory);
        classToTest.myMethod("the request body");
        verify(mockClient).send(argThat(request -> request.uri().equals(URI.create("http://localhost:8080/api"))), any());
    }
}
km0tfn4u

km0tfn4u2#

你可以试着这样做:

when(client.send(request, HttpResponse.BodyHandlers.ofString()).thenReturn(response)

when(client.send(any(), anyString()).thenReturn(response)

响应可以是模拟对象,也可以根据需要创建响应
然后你可以测试assertEquals((expectedResult, yourmethod())

piztneat

piztneat3#

我正在使用HttpClient调用外部API,如下所示:
String getString = String. getString();HttpRequest request = HttpRequest.newBuilder().uri(URI.create(“http://localhost:8080/api”)).POST(BodyPublishers.ofString(requestBody)).header(“Authorization”,authorizationHeader).header(“Content-Type”,“application/json”).build();
HttpResponse response = client.send(request,HttpResponse.BodyHandlers.ofString());

相关问题