kyucumber
전체 글 보기

RestHighLevelClient 테스트 작성 시 SearchResponse 더미 데이터 생성하기

Spring에서 RestHighLevelClient 관련 unit 테스트 작성시 SearchResponse 더미 데이터 생성을 위한 코드를 작성했습니다. 관련 내용을 정리합니다.

SearchResponse 데이터 생성을 위한 Util 클래스 정의

ElasticsearchTestUtils.kt

object ElasticsearchTestUtils { fun getSearchResponseFromJson(jsonResponse: String): SearchResponse { try { val registry = NamedXContentRegistry(getDefaultNamedXContents()) val parser: XContentParser = JsonXContent.jsonXContent.createParser(registry, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, jsonResponse) return SearchResponse.fromXContent(parser) } catch (e: IOException) { println("exception $e") } catch (e: Exception) { println("exception $e") } throw IllegalStateException("invalid state") } private fun getDefaultNamedXContents(): List<NamedXContentRegistry.Entry> { val map: MutableMap<String, ContextParser<Any, out Aggregation>> = HashMap() map[TopHitsAggregationBuilder.NAME] = ContextParser { p: XContentParser?, c: Any? -> ParsedTopHits.fromXContent(p, c as String?) } map[StringTerms.NAME] = ContextParser { p: XContentParser?, c: Any? -> ParsedStringTerms.fromXContent(p, c as String?) } return map.entries.stream() .map { entry: Map.Entry<String, ContextParser<Any, out Aggregation>> -> NamedXContentRegistry.Entry( Aggregation::class.java, ParseField(entry.key), entry.value ) }.toList() } }

SearchResponse 생성을 위한 json 파일 생성

test/resources/json/search.json

{ "took" : 3, "timed_out" : false, "_shards" : { "total" : 6, "successful" : 6, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 1.0, "hits" : [ { "_index" : "index", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : { } } ] } }

RestHighLevelClient mocking이 필요한 테스트 작성

describe("elasticsearch client unit test") { val elasticsearchClient = mockk<RestHighLevelClient>() val lastAccessService = LastAccessSearchService( elasticsearchClient = elasticsearchClient, fullAuthAccessInfoDeserializer = FullAuthAccessInfoDeserializer() ) context("key를 통해 검색하는 경우") { val query = Query() val key = "key" it("해당 key에 해당하는 모든 유저 목록을 불러온다") { val searchResponse: SearchResponse = ElasticsearchTestUtils.getSearchResponseFromJson(ClassPathResource("json/search.json").file.readText()) every { elasticsearchClient.search(query.createRequest(), RequestOptions.DEFAULT) } answers { searchResponse } val searchResults = elasticsearchService.search(key) assertThat(searchResults[0].key).isEqualTo(key) } } }

위와 같이 정의하고 사용하다 보니 Aggregation Query 결과에 대한 부분은 제대로 파싱되지 않아 제대로 사용하긴 어려워 보였습니다. 그리고 이렇게 까지 해서 단위 테스트를 작성해야 할까 싶은 생각이 드네요…

Reference