Reputation: 283
I need to write unit tests for doing a paginated network request. First I implemented paging library logic to retrieve the data. I created a data source class and a repository class to get data from the network request.
This is my data source class
class ListDataSource(
private val networkService: NetworkService,
private val searchKey: String) : PagingSource<Int, ListItem>() {
override fun getRefreshKey(state: PagingState<Int, ListItem>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ListItem> {
val pageNumber: Int = params.key ?: 0
return try {
val response = networkService.getList(
searchTerm = searchKey,
page = pageNumber,
size = 30
)
val listItems = response.response?.list
val nextKey = listItems?.let { nonNullList ->
if (nonNullList.size < 30) {
null
} else {
pageNumber + 1
}
} ?: run {
null
}
LoadResult.Page(
data = listItems.orEmpty(),
prevKey = if (pageNumber == 0) null else pageNumber - 1,
nextKey = nextKey
)
} catch (exception: Exception) {
LoadResult.Error(exception)
}
}}
This is my repository class
class ListPagingRepository(private val service: NetworkService) {
private lateinit var pager: Pager<Int, ListItem>
private lateinit var pagingSource: ListDataSource
fun getListPager(): Pager<Int, ListItem> {
return pager
}
fun isPagerInitialized(): Boolean = this::pager.isInitialized
fun createSource(searchTerm: String) {
pagingSource = ListDataSource(service, searchTerm)
}
fun createPager() {
pager = Pager(
config = PagingConfig(
initialLoadSize = 15,
pageSize = 15,
enablePlaceholders = false,
prefetchDistance = 2
),
pagingSourceFactory = { pagingSource }
)
}}
Inside my viewmodel I the function to do the network call is:
fun getPaginatedList(searchTerm: String): Flow<PagingData<ListItem>> {
listPagingRepository.createSource(searchTerm)
listPagingRepository.createPager()
return if (listPagingRepository.isPagerInitialized()) {
listPagingRepository
.getListPager()
.flow
.cachedIn(viewModelScope)
.map { pagingData -> pagingData.map { listMapper.map(it) } }
} else emptyFlow()
}
How can I test this network request? Searched for 2 days but nothing that I found helped me.
Upvotes: 0
Views: 664
Reputation: 254
You should test your implementation, with mocked network responses. An example of such a test with MockK as the mocking framework :
@Test
fun `verify error return from load() when a (types of responses you expect to potentially receive) response is returned` () = runTest {
val mockNetworkService = mockk<NetworkService>(relaxed = true, relaxedUnitFun = true)
val testParams = LoadParams(1, false)
every { mockNetworkService.getList(any(), any(), any()) } returns LoadResponse.Error(YourExpectedException)
val result = ListDataSource(mockNetworkService, "test search").load(testParams)
assertEquals(LoadResponse.Error(YourExpectedException), result)
}
Upvotes: 0