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 결과에 대한 부분은 제대로 파싱되지 않아 제대로 사용하긴 어려워 보였습니다. 그리고 이렇게 까지 해서 단위 테스트를 작성해야 할까 싶은 생각이 드네요…