模拟 Java 11 HttpClient?

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

我一直在尝试模拟 Java 11 的 HttpClient 但遇到了麻烦。这是我到目前为止所拥有的:

public class ApiPokerTest {
HttpClient client = mock(HttpClient.class);

@Test
public void poking_api_returns_list_of_modules() throws Exception {
    HttpResponse<String> resp = mock(HttpResponse.class);
    when(resp.body()).thenReturn("Hello world");
    when(client.send(any(), any())).thenReturn(resp);
}

}

这不起作用,因为 any() 与 HttpResponse 类型不匹配。我想要的只是当客户端调用 send() 时,它会返回带有给定 JSON 的模拟响应。我该怎么做?

mocking mockito httpclient
3个回答
1
投票

使用mockito

@Spy

@ExtendWith(MockitoExtension.class) // using junit5


@Mock 
HttpResponse<InputStream> mockResponse;

@Spy 
HttpClient httpClient;

void test() throws Exception {
  when(httpClient.send(any(), any(HttpResponse.BodyHandlers.ofInputStream().getClass())))
    .thenReturn(mockResponse);
  // ...
}

0
投票

Mockito
无法开箱即用地模拟
final
类(HttpClientImpl 就是这样的类)。使用
Spock
及其
MockingApi
。使用这个测试框架,您可以编写如下测试用例:

given:
def client = Mock(HttpClient)

when:
def response = Mock(HttpResponse)
def responseBody = { 'Hello world' } as Supplier<String>
1 * response.body() >> responseBody
1 * client.send(_ as HttpRequest, _ as HttpResponse.BodyHandler) >> response
def mockedResponseBody = client.send(HttpRequest.newBuilder()
    .uri(new URI('http://localhost:8080'))
    .build(), HttpResponse.BodyHandlers.discarding()).body()

then:
mockedResponseBody.get() == responseBody.get()

如果您坚持使用 Mockito,则必须在

mocito-extensions
中添加
test\resources
目录,其中包含
org.mockito.plugins.MockMaker
文件,其中包含行
mock-maker-inline


0
投票

出于某种原因,我花了一个多小时才弄清楚,并在 Stack Overflow 上尝试了各种解决方案。最后@ezer的回答帮助了我,我什至不必使用@Spy。

我只是嘲笑这两件事:


@ExtendWith(MockitoExtension.class)
public class MyTest {

  @Mock HttpResponse<String> response;
  @Mock HttpClient httpClient;

  ...

我确保

sendAsync
返回模拟的响应:


when(httpClient.sendAsync(any(), any(HttpResponse.BodyHandlers.ofString().getClass())))
    .thenReturn(CompletableFuture.completedFuture(response));

最后让模拟的响应返回我想要的。我只关心身体:

when(response.body()).thenReturn("A mocked response!");

我认为我缺少的钥匙是

HttpResponse.BodyHandlers.ofString().getClass()
。之前,我一直收到错误,因为
sendAsync
的第二个参数是泛型 T。我认为指定类可以解决泛型参数问题。

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