최근에 회사 일로 검색 서비스를 개발했다. 검색 엔진으로는 Elastic Search를 사용했고, 매일 최한시(off-peak time)에 한 번씩 운영 데이터베이스에서 검색, 필터링, 정렬, Aggregation 등에 필요한 컬럼만 골라 인덱싱하도록 설계했다. 그리고, 재고 수량과 같이 실시간 업데이트가 필요한 값 들은 다른 서비스에서 SNS 메시지 또는 메시지 큐를 이용해서 전달하고, 전달 받은 값을 인덱싱에 반영하도록 구현했다.
Elastic Search는 사용법이 복잡하긴 하지만, 인덱싱된 필드 값에 따라 내림차순, 오름차순으로 미리 정렬된 결과를 받을 수 있다. 그런데, 아무리 실시간 업데이트를 한다고 해도, 인덱싱된 값만으로 정렬이 불가능한 경우가 있고, 이 경우에는 검색 결과를 받아서 후 처리로 배열을 순회하면서 다시 정렬을 해야 한다. 같은 클래스의 Public 메서드가 정렬 요청을 하므로, 당연히 Protected 메서드로 구현했다.
일반적으로 알려진 테스트 모범 사례는 다음과 같다.
- 내가 짠 코드만 테스트한다. 외부에서 가져온 라이브러리를 테스트할 이유는 없다.
- Public 메서드만 테스트한다. Private나 Protected 메서드는 Public 메서드가 작동하는데 도움을 주는 메서드들이므로, Public 메서드를 테스트함으로써 자동으로 테스트된다.
후처리 정렬의 정상 작동을 확인해야 할 필요성이 생긴 것이다. 물론 구현한 Protected 메서드의 가시성을 Public으로 변경하면 쉽다. 그런데, 다른 클래스에서 호출하지도 않을 메서드를 Public으로 선언하는 것은 기분이 찜찜하다. 이 포스트에서는 Private나 Protected로 선언된 메서드를 유닛 테스트하는 방법을 설명한다. 결론부터 말하면, PHP의 Reflection
API를 이용하는 것이다.