当前位置: 首页 > 知识库问答 >
问题:

RestHighLevelClient JUnit测试返回NullPointerException

席言
2023-03-14

我目前正在研究如何测试我的ElasticSearch类的覆盖率,它实现了ResHighLevel客户端。问题是它返回指向RestHighLevelClient.class.的空指针,我是ES的新手,我不知道我哪里出错了。

这是我的ElasticSearch类:

@Service
public class ElasticsearchService {

    @Autowired
    private LoggingService loggingService;

    @Autowired
    private LocationService locationService;

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private ObjectMapper mapper;

    @Autowired
    private Utils util;

    @Autowired
    private ApplicationProperties prop;

    public String addAtmStatusRecord(ATM atm) throws IOException {
        GeoPoint geoPoint = locationService.getLocation(atm.getTerminalId());

        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject()
            .field("terminalId", atm.getTerminalId())
            .field("atmStatus", "D".equals(atm.getAtmStatus()) ? 1 : 0)
            .field("atmLocation", atm.getAtmLocation())
            .field("errorDescription", atm.getErrorDescription())
            .field("lastTranTime", atm.getLastTranTime())
            .field("lastDevStatTime", atm.getLastDevStatTime())
            .field("errorCode", atm.getErrorCode())
            .field("termBrcode", atm.getTermBrcode())
            .timeField("@timestamp", new Date())
            .latlon("location", geoPoint.getLat(), geoPoint.getLon())
            .endObject();

        IndexRequest indexRequest = new IndexRequest(prop.getEsIndex(), prop.getEsType(), atm.getTerminalId()).source(builder);
        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
        loggingService.log(this.getClass().toString(), atm.getTerminalId(), TraceLog.SUCCESSFUL_PUSH_TO_ELASTIC_SEARCH, 
                util.mapToJsonString(atm));

        return response.getResult().name();
    }



    public List<AtmElasticSearchData> searchForOfflineAtmData() throws IOException {
        SearchResponse searchResponse = getAllOfflineAtmData();
        List<SearchHit> searchHits = Arrays.asList(searchResponse.getHits().getHits());
        List<AtmElasticSearchData> listOfAtm = new ArrayList<>();

        for (SearchHit searchHit : searchHits) {
            listOfAtm.add(mapper.readValue(searchHit.getSourceAsString(), AtmElasticSearchData.class));
        }

        return listOfAtm;
    }

    public SearchResponse getAllOfflineAtmData() throws IOException {
        Map<String, Object> queryParam = new HashMap<>();   
        queryParam.put("atmStatus", 1);
        return retrieveElasticSearchData(queryParam);
    }

    public long getAllOfflineAtmCount() throws IOException {
        return getAllOfflineAtmData().getHits().getTotalHits();
    }

    private SearchResponse retrieveElasticSearchData(Map<String, Object> queryParams) throws IOException {
        SearchSourceBuilder searchSourceBuilder  = new SearchSourceBuilder();

        queryParams.entrySet().forEach(queryParam -> searchSourceBuilder.query(
                QueryBuilders.termQuery(queryParam.getKey(), queryParam.getValue())));
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(Integer.parseInt(prop.getEsMaxSearchSize()));
        SearchRequest searchRequest = new SearchRequest(prop.getEsIndex())
                .types(prop.getEsType())
                .source(searchSourceBuilder);

        return client.search(searchRequest, RequestOptions.DEFAULT);
    }
}

这是我的测试案例:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ATMMonitoringApplication.class, initializers = ConfigFileApplicationContextInitializer.class)
public class ElasticsearchServiceTest {

    @Autowired
    private ElasticsearchService elasticsearchService;

    @MockBean
    private LoggingService loggingService;

    @MockBean
    private LocationService locationService;

    @MockBean
    private RestHighLevelClient client;

    @MockBean
    private ObjectMapper mapper;

    @MockBean
    private Utils util;

    @MockBean
    private IndexRequest indexRequest;
    @MockBean IndexResponse indexResponse;

    @Value("${elastic.search.atm.monitoring.index}")
    private String esIndex;

    @Value("${elastic.search.atm.monitoring.type}")
    private String esType;

    private ATM atm;

    @Before
    public void setUp() throws ParseException, IOException {

        client = mock(RestHighLevelClient.class);
        indexRequest = mock(IndexRequest.class);
        indexResponse = mock(IndexResponse.class);

        MockitoAnnotations.initMocks(this);
        atm = new ATM();
        atm.setAtmLocation("location");
        atm.setAtmStatus("U");
        atm.setErrorCode("222");
        atm.setErrorDescription("STATUS");
        atm.setLastDevStatTime(null);
        atm.setLastTranTime(null);
        atm.setTerminalId("123");
        atm.setTermBrcode("111");

    }

    @Test
    public void testAddAtmStatusRecordIsNull() throws IOException, NumberFormatException, IllegalArgumentException, IllegalAccessException {

        Mockito.when(locationService.getLocation(Mockito.anyString())).thenReturn(new GeoPoint(121.00000, 11.9874));
        elasticsearchService.addAtmStatusRecord(atm);
        assertThat(1).isEqualTo(1);
    }
        @Test
    public void testAddAtmStatusRecordAtmIsDown() throws IOException {
        ATM atm = new ATM();
        atm.setAtmStatus("D");
        Mockito.when(locationService.getLocation(Mockito.anyString())).thenReturn(new GeoPoint(121.00000, 11.9874));
        elasticsearchService.addAtmStatusRecord(atm);
        assertThat(1).isEqualTo(1);
    }

    @Test
    public void testGetAllOfflineAtmCount() throws IOException {

        elasticsearchService.getAllOfflineAtmCount();
        assertThat(1).isEqualTo(1);

    }

    @Test
    public void testsearchForOfflineAtmData() throws IOException {

        List<AtmElasticSearchData> atmEsData = new ArrayList<>();
            elasticsearchService.searchForOfflineAtmData();

        assertThat(1).isEqualTo(1);
    }


}

我的端口已在app.properties中设置为9200。

请在这方面给我一些帮助。我真的需要解决这个问题。任何帮助都将不胜感激。

共有1个答案

金坚
2023-03-14

RestHighLevelClient 中的大多数方法都是最终的,因此不能被模拟并调用实际方法并抛出空指针。请参阅这篇文章 NullPointerException 问题 当试图模拟 Elastic Search 的 RestHighLevelClient 时

 类似资料:
  • 我试着去模拟课堂,但我总是得到一个NPE。我见过当stubing方法时发布mockito-nullPointerException。在这篇文章中,他们这样解释: 我几乎可以肯定这也适用于我的问题。但我找不到解决办法。我已经试了10个小时了。 我还读了一些关于@autowired和@before的东西,显然@autowired是在@before之前创建的,这也可以解释我的NPE。 在@test vo

  • 我试图测试我的RestController代码(Spring Boot项目),但我总是得到404。以下是我目前掌握的情况: } } 结果总是这样: 我做错了什么?我已经尝试过直接在setUp方法中用标准设置()初始化mockmvc,我还使用了@SpringBootTest和@AutoConfigreMockMvc相结合。 有人有什么有用的提示吗?我使用spring boot 2.1.4。 谢谢

  • 问题内容: 在尝试JUnit时,我尝试如下测试一个简单的私有方法,该方法接收String并确保其中不包含单词’Dummy’。 我知道,可以将测试 与类 放在同一包 中,并将方法的访问修饰符更改为包,但是我想使用反射来学习这一点。 我试图通过反射访问私有方法,但测试失败!它显示以下异常: 基于这个问题的答案,我也正在抓。 JUnit的 问题答案: 我在上面的评论中同意@Stultuske,并将测试重

  • 我试图实现一个单元测试的在与。 我在关注这个链接,它运行良好,但结果为空,当我用浏览器测试我的websocket时,它会发送所需的结果。 让我展示一下我的测试课 } 这是我的< code > WebSocketConfiguration 类 } 这是我从服务器得到的响应 更新: 在下面的答案中添加建议的更改并经过进一步的研究后,我的测试类现在看起来像这样 } 经过这些更改后,我现在可以将堆栈跟踪打

  • 测试方法: 测试用例:

  • 我正在尝试为我的Spring项目运行集成测试,它是一个简单的get方法,用于从DB返回给定id的字符串输出。但是在Mockmvc中,我一直在Mockmvc上得到一个NullPointerException。在我的测试范围内执行。 以下是测试: 这里是控制器-输出控制器: 完全错误是: