본문 바로가기

Android

PagingData Unit Test 하기

반응형

앱 내에서는 PagingDataAdapter의 snapshot()을 호출하여 PagingData를 리스트로 반환할 수 있습니다.

다만, PagingDataAdapter는 View를 포함하고 있기 때문에 Unit Test 내에서 사용할 수 없습니다. Instrumented Test로 구현하자니... 느리기도 하고 같은 맥락을 가진 테스트가 여러 곳으로 파편화 되기 때문에 고민할 수 밖에 없었습니다.

PagingDataAdapter의 내부 구현을 보면 다음과 같이 differ의 snapshot을 호출하는 것을 확인할 수 있습니다.

differ는 AsyncPagingDataDiffer 인스턴스입니다.

AsyncPagingDataDiffer를 그대로 사용하면 될까요? 가능은 합니다. 다만, AsyncPagingDataDiffer 또한 내부적으로 differBase를 가지고 있고, 해당 멤버변수의 snapshot 메소드를 호출하고 있습니다. 더 간단한 클래스가 존재한다는 의미입니다.

또한, AsyncPagingDataDiffer의 경우 넣어줘야할 파라미터가 많습니다.

differBase는 다음과 같이 추상 클래스 PagingDataDiffer를 상속하고 있습니다.

PagingDataDiffer 또한 내부적으로 PagePresenter를 사용하고 있지만, 해당 클래스는 internal class라서 접근이 불가능합니다.

즉, PagingDataDiffer를 적절히 구현하면 Unit Test에서도 PagingData의 snapshot을 계산할 수 있습니다. callback 기능이 필요하지 않으니 DifferCallback은 빈 함수로 구성하고, dispatcher를 파라미터로 받아 test dispatcher를 넘길 수 있도록 하면 됩니다.

presentNewList는 추상 메소드이므로 필수 구현 해주시고, onListPresentable()을 호출하지 않으면 에러가 발생하니 주의하시기 바랍니다.

fun <T : Any> createPagingDataDiffer(dispatcher: CoroutineDispatcher): PagingDataDiffer<T> {
    val differCallback = object : DifferCallback {
        override fun onChanged(position: Int, count: Int) {}
        override fun onInserted(position: Int, count: Int) {}
        override fun onRemoved(position: Int, count: Int) {}
    }
    
    return object : PagingDataDiffer<T>(differCallback, dispatcher) {
        override suspend fun presentNewList(previousList: NullPaddedList<T>, newList: NullPaddedList<T>, lastAccessedIndex: Int, onListPresentable: () -> Unit): Int? {
            onListPresentable()
            return null
        }
    }
}

 

반응형