如何为Java中的Elasticsearch编写适当的单元测试

时间:2018-11-05 03:14:41

标签: java unit-testing spring-boot elasticsearch junit

概述:

我对Elastic搜索测试完全陌生,我将添加适当的单元测试。项目兼容性如下:

  • Java 8
  • Elasticsearch 6.2.4
  • 项目使用低级Rest客户端从ES中获取数据

有关ES配置的更多信息如下:

import static java.net.InetAddress.getByName;
import static java.util.Arrays.stream;

import java.net.UnknownHostException;
import java.util.Map;
import java.util.Objects;

import javax.inject.Inject;

import org.apache.http.HttpHost;

import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import au.com.api.util.RestClientUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class ElasticConfiguration implements InitializingBean{

    @Value(value = "${elasticsearch.hosts}")
    private String[] hosts;

    @Value(value = "${elasticsearch.httpPort}")
    private int httpPort;

    @Value(value = "${elasticsearch.tcpPort}")
    private int tcpPort;

    @Value(value = "${elasticsearch.clusterName}")
    private String clusterName;

    @Inject
    private RestClientUtil client;

    @Bean
    public RestHighLevelClient restHighClient() {

        return new RestHighLevelClient(RestClient.builder(httpHosts()));
    }

    @Bean
    @Deprecated
    public RestClient restClient() {

        return RestClient.builder(httpHosts()).build();

    }

    /**
     * @return TransportClient
     * @throws UnknownHostException
     */
    @SuppressWarnings("resource")
    @Bean
    public TransportClient transportClient() throws UnknownHostException{

        Settings settings = Settings.builder()
                .put("cluster.name", clusterName).build();

        return new PreBuiltTransportClient(settings).addTransportAddresses(transportAddresses());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug("loading search templates...");
        try {
            for (Map.Entry<String, String> entry : Constants.SEARCH_TEMPLATE_MAP.entrySet()) {
                client.putInlineSearchTemplateToElasticsearch(entry.getKey(), entry.getValue());
            }
        } catch (Exception e) {
            log.error("Exception has occurred in putting search templates into ES.", e);
        }
    }

    private HttpHost[] httpHosts() {
        return stream(hosts).map(h -> new HttpHost(h, httpPort, "http")).toArray(HttpHost[]::new);
    }

    private TransportAddress[] transportAddresses() throws UnknownHostException {
        TransportAddress[] transportAddresses = stream(hosts).map(h -> {
            try {
                return new TransportAddress(getByName(h), tcpPort);
            } catch (UnknownHostException e) {
                log.error("Exception has occurred in creating ES TransportAddress. host: '{}', tcpPort: '{}'", h, tcpPort, e);
            }
            return null;
        }).filter(Objects::nonNull).toArray(TransportAddress[]::new);

        if (transportAddresses.length == 0) {
            throw new UnknownHostException();
        }
        return transportAddresses;
    }
}

问题:

如果不在计算机上运行独立的ES,我不知道如何模拟ES或如何测试ES。请使用以下类作为示例,让我知道如何为getSearchResponse方法编写一个测试用例(单元测试不集成):

    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;

    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.transport.NoNodeAvailableException;
    import org.elasticsearch.client.transport.TransportClient;
    import org.elasticsearch.script.ScriptType;
    import org.elasticsearch.script.mustache.SearchTemplateRequestBuilder;
    import org.elasticsearch.search.Scroll;
    import org.elasticsearch.search.aggregations.Aggregation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.MessageSource;
    import org.springframework.stereotype.Repository;
    @Slf4j
@Repository
@NoArgsConstructor
public abstract class NewBaseElasticsearchRepository {

    @Autowired
    protected NewIndexLocator newIndexLocator;

    @Value(value = "${elasticsearch.client.timeout}")
    private Long timeout;

    @Autowired
    protected TransportClient transportClient;

    @Autowired
    protected ThresholdService thresholdService;

    @Autowired
    protected MessageSource messageSource;

    /**
     * @param script         the name of the script to be executed
     * @param templateParams a map of the parameters to be sent to the script
     * @param indexName      the index to target (an empty indexName will search all indexes)
     *
     * @return a Search Response object containing details of the request results from Elasticsearch
     *
     * @throws NoNodeAvailableException thrown when the transport client cannot connect to any ES Nodes (or Coordinators)
     * @throws Exception                thrown for all other request errors such as parsing and non-connectivity related issues
     */
    protected SearchResponse getSearchResponse(String script, Map<String, Object> templateParams, String... indexName) {
        log.debug("transport client >> index name --> {}", Arrays.toString(indexName));

        SearchResponse searchResponse;

        try {
            searchResponse = new SearchTemplateRequestBuilder(transportClient)
                .setScript(script)
                .setScriptType(ScriptType.STORED)
                .setScriptParams(templateParams)
                .setRequest(new SearchRequest(indexName))
                .execute()
                .actionGet(timeout)
                .getResponse();
        } catch (NoNodeAvailableException e) {
            log.error(ELASTIC_SEARCH_EXCEPTION_NOT_FOUND, e.getMessage());
            throw new ElasticSearchException(ELASTIC_SEARCH_EXCEPTION_NOT_FOUND);
        } catch (Exception e) {
            log.error(ELASTIC_SEARCH_EXCEPTION, e.getMessage());
            throw new ElasticSearchException(ELASTIC_SEARCH_EXCEPTION);
        }

        log.debug("searchResponse ==> {}", searchResponse);
        return searchResponse;
    }

因此,如果您能看一下示例类,并在这里与我分享您的真实解决方案,以了解如何模拟TransportClient并从{{1}得到正确的答复,我将不胜感激。 }对象。


注意:

  • 我尝试使用SearchResponse中的ESTestCase,但是遇到了org.elasticsearch.test:framework:6.2.4问题,无法解决。同时,我通常找不到任何与此文档或Java ES单元测试相关的文档。

0 个答案:

没有答案