【问题标题】:Mocking execte() method of HttpClient [duplicate]模拟HttpClient的execte()方法[重复]
【发布时间】:2019-07-26 19:55:14
【问题描述】:

我想模拟HttpClassexecute 方法以返回一个虚拟响应,但我的测试代码正在执行请求。

类代码 -

class MyService {

    private CloseableHttpClient newHttpClient() {

        try {
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(TrustAllStrategy.INSTANCE).build(),
                    NoopHostnameVerifier.INSTANCE);

            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException exception) {
            logger.error(exception);
        }

        return null;
    }

    public String create(CreateRequestDTO Request) {

        CloseableHttpClient client = newHttpClient();
        CloseableHttpResponse response = null;

        HttpPut httpPut = new HttpPut("MyUrl...");

        try {
            response = client.execute(httpPut);
        } catch (IOException exception) {
            return "exception";
        }
        return response.toString();
    }
}

测试类代码 -

@PrepareForTest({ MyService.class })
@PowerMockIgnore({ "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*",
        "javax.activation.*", "javax.management.*", "javax.net.ssl.*", "javax.crypto.*" })
@RunWith(PowerMockRunner.class)
public class MyServiceTest {

    @InjectMocks
    private MyService MyService;

    @Mock
    private CloseableHttpClient closeableHttpClient;

    @Mock
    private HttpClient httpClient;

    @Mock
    private CloseableHttpResponse closeableHttpResponse;

    @Mock
    private HttpPut httpPut;

    @Mock
    private HttpEntity httpEntity;

    @Before
    public void setupTest() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testCreate() throws Exception {
        // MyService MyServiceSpy = PowerMockito.spy(MyService);
        MyService MyServiceSpy = PowerMockito.spy(MyService);
        CreateRequestDTO createRequestDTO = new CreateRequestDTO();
        createRequestDTO.setLocation("room 1");
        createRequestDTO.setStartTime("3 pm");
        createRequestDTO.setEndTime("4 pm");

        try {

            PowerMockito.doReturn(closeableHttpClient).when(MyServiceSpy, "newHttpClient");

            // PowerMockito.when(MyServiceSpy,
            // "newHttpClient").thenReturn(httpClient);

            // PowerMockito.verifyPrivate(MyServiceSpy).invoke("newHttpClient");

            String jsonEntity = " created successfully";

            HttpEntity httpEntity = EntityBuilder.create().setText(jsonEntity)
                    .setContentType(org.apache.http.entity.ContentType.APPLICATION_JSON).build();

            closeableHttpResponse.setEntity(httpEntity);

            PowerMockito.doReturn(closeableHttpResponse).when(closeableHttpClient).execute(any(HttpPut.class));
            // PowerMockito.doReturn(closeableHttpResponse).when(httpClient).execute(any(HttpPut.class));

            String res = MyService.create(createRequestDTO);
            logger.info("Result from create : " + res);
            Assert.assertTrue(res.substring(0, 5).matches("BEGIN"));

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

}

我尝试过用 Mockito 代替 PowerMockito,但仍然会实际执行请求。

【问题讨论】:

  • Mocked HttpClient calls actual method 的可能重复项。如前所述(在原始线程中),需要重构服务代码以便可以使用模拟。当前形式的行为符合预期。
  • 这是必需的吗 MyService MyServiceSpy = PowerMockito.spy(MyService);

标签: java unit-testing powermockito java-http-client


【解决方案1】:

您的问题不在于模拟客户端,而在于构建它。 目前,当您使用 HttpClients.custom() 静态方法时,您的代码会构建一个新客户端而不是模拟。

因为你需要模拟一个静态方法,你需要PowerMockito.mockStatic()

首先您需要将HttpClients 添加到您的@PrepareForTest 注释中,然后您应该这样做:

PowerMockito.mockStatic(HttpClients.class);
when(HttpClients.custom()).thenReturn(mockedBuilder);
when(mockedBuilder.setSSLSocketFactory(any(SSLSocketFactory.class)).theReturn(mockedBuilder);
when(mockedBuilder.build()).thenReturn(httpClient);// your mock object

【讨论】:

  • 1.我正在使用私有方法的模拟返回模拟的 http 客户端,这不正确吗? 2. 在您建议的解决方案中,什么是 mockedBuilder?
  • 我尝试使用 @Mock private HttpClientBuilder mockedBuilder; 模拟 Http 客户端构建器,但在线 when(mockedBuilder.setSSLSocketFactory(any(SSLSocketFactory.class)).thenReturn(mockedBuilder); 上出现错误 org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here:
猜你喜欢
  • 2021-11-04
  • 1970-01-01
  • 2017-06-25
  • 2018-07-17
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2019-06-29
相关资源
最近更新 更多