【问题标题】:How to write JUnit TestClass for ConnectionPool config Class如何为连接池配置类编写 JUnit 测试类
【发布时间】:2021-11-30 22:00:10
【问题描述】:

如何为下面的类编写一个 JUnit 测试类? 当我尝试写作时,我得到了 "Cannot locate declared field com.bs.proteo.microservices.channels.sessionmobileadapter.business.openam.resource.ConnPoolConfig.connPoolRouteSize" 错误。

public class ConnPoolConfig {

    @Bean(name = "openAmHttpClient")
    public HttpClient buildConnectionPool(
            @Value("${login.connectionpool.route.size:10}") int connPoolRouteSize,
            @Value("${login.connectionpool.size:10}") int connPoolSize,
            @Value("${login.connectionpool.ttl:60}") int connPoolTtl,
            @Value("${login.connectionpool.evictidle:30}") int connPoolEvictIdle,
            @Value("${connection.http.timeout.connection.request}:5000") int connRequestTimeout,
            @Value("${connection.http.timeout.connect:5000}") int connectTimeout,
            @Value("${connection.http.timeout.socket:30000}") int socketTimeout){

        RequestConfig config = RequestConfig.custom()
                .setConnectionRequestTimeout(connRequestTimeout)
                .setConnectTimeout(connectTimeout)
                .setSocketTimeout(socketTimeout)
                .build();

        final HttpClient httpClient = HttpClientBuilder.create()
                .disableCookieManagement()
                .setMaxConnPerRoute(connPoolRouteSize)
                .setMaxConnTotal(connPoolSize)
                .setConnectionTimeToLive(connPoolTtl, TimeUnit.SECONDS)
                .setDefaultRequestConfig(config)
                .evictIdleConnections(connPoolEvictIdle, TimeUnit.SECONDS)
                .build();

        return httpClient;
    }
}

【问题讨论】:

    标签: java spring-boot junit microservices


    【解决方案1】:

    你有不同的选择。在下面的示例中,我将仅使用引用 HttpClientBuilder 的几行代码,但您可以在代码中的任何地方使用相同的机制。

    使用 Power Mockito

    您可以使用PowerMockito 来模拟第一个静态调用。

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({HttpClientBuilder.class})
    public class MyJunit{
        
       @Test
       public void myTest() {
          HttpClientBuilder client = Mockito.mock(HttpClientBuilder.class);
          PowerMockito.when(HttpClientBuilder.create()).thenReturn(client);
          myclassUnderTest.buildConnectionPool(...);
          Mockito.verify(client).disableCookieManagement();
    
       }
    }
    

    PowerMockito 有一些缺点;例如:

    1. 由于覆盖静态方法所需的开销,您的测试会变慢
    2. 如果您使用JaCoCo 来跟踪您的代码覆盖率,那么它将不再起作用。

    重构你的代码

    这里唯一的区别是避免使用 PowerMockito 并以测试友好的方式重构您的测试类。 这里的重点是用受保护的方法包装静态方法调用;然后我们将模拟刚刚创建的所有这些方法,以便返回一个模拟对象,用于逐次验证设置。

    让我们在你的测试类中添加这样的方法

    
     protected HttpClientBuilder create(){
        return HttpCLientBuilder.create();
     }
    
    

    现在,您的测试方法将是这样的

     @Test
     public void myTest(){
        HttpClientBuilder client = Mockito.mock(HttpClientBuilder.class);
        Mockito.doReturn(client).when(myclassUnderTest).create();
        myClassUnderTest.buildConnectionPool(...);
        Mockito.verify(client).disableCookieManagement();
    }
    
    

    【讨论】:

    • 不错的答案,但有必要提到 PowerMockito 不适用于 Junit5 - 但幸运的是 3.4.0 版的普通旧 Mockito 具有模拟静态方法,包括用于 Junit5。 stackoverflow.com/questions/52830441/…
    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2022-11-04
    • 1970-01-01
    相关资源
    最近更新 更多