というリポジトリ クラスに関数がありますgetAll()
。私の質問は、この機能をテストするにはどうすればよいですか? getAll()
関数内のコードは次のとおりです。
fun getAll(): Flow<PagingData<Movie>> {
return Pager(
config = PagingConfig(enablePlaceholders = false, pageSize = 20),
pagingSourceFactory = { MoviesPagingSource(movieApiService) }
).flow
}
これが MoviesPagingSource クラスの内部です。
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.oazisn.moviecatalog.data.local.entity.Movie
class MoviesPagingSource(
private val service: MovieApiService,
) : PagingSource<Int, Movie>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Movie> {
val page = params.key ?: 1
return try {
val response = service.getPopular(page)
val movies = ArrayList<Movie>()
response.results?.forEach { data ->
movies.add(
Movie(
"https://image.tmdb.org/t/p/original${data?.posterPath}",
data?.title ?: "-",
data?.voteAverage ?: 0.0,
data?.id ?: 0
)
)
}
LoadResult.Page(
data = movies,
prevKey = if (page == 1) null else page - 1,
nextKey = if (page == response.totalPages) null else page + 1
)
} catch (exception: Exception) {
LoadResult.Error(exception)
}
}
override fun getRefreshKey(state: PagingState<Int, Movie>): Int? {
// Try to find the page key of the closest page to anchorPosition, from
// either the prevKey or the nextKey, but you need to handle nullability
// here:
// * prevKey == null -> anchorPage is the first page.
// * nextKey == null -> anchorPage is the last page.
// * both prevKey and nextKey null -> anchorPage is the initial page, so
// just return null.
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}
}
PagingData
Paging v3 Android ライブラリのクラスです。https://developer.android.com/topic/libraries/architecture/paging/v3-overview
これまでに試した単体テストは次のとおりです。
@Test
fun getAll() {
testCoroutineRule.runBlockingTest {
val dummyList = listOf(
MovieResultItem(
posterPath = "/6Wdl9N6dL0Hi0T1qJLWSz6gMLbd.jpg",
title = "Mortal Kombat",
voteAverage = 7.9,
id = 460465
),
MovieResultItem(
posterPath = "/pgqgaUx1cJb5oZQQ5v0tNARCeBp.jpg",
title = "Godzilla vs. Kong",
voteAverage = 8.2,
id = 399566
),
MovieResultItem(
posterPath = "/oBgWY00bEFeZ9N25wWVyuQddbAo.jpg",
title = "Nobody",
voteAverage = 8.5,
id = 615457
),
MovieResultItem(
posterPath = "/tnAuB8q5vv7Ax9UAEje5Xi4BXik.jpg",
title = "Zack Snyder's Justice League",
voteAverage = 8.5,
id = 791373
)
)
val dummyObject = ListBaseResponse(
results = dummyList
)
`when`(movieApiService.getPopular(1)).thenReturn(dummyObject)
val movies = ArrayList<Movie>()
dummyObject.results?.forEach { data ->
movies.add(
Movie(
"https://image.tmdb.org/t/p/original${data?.posterPath}",
data?.title ?: "-",
data?.voteAverage ?: 0.0,
data?.id ?: 0
)
)
}
val response = repository.getAll()
val repoResponseAsLiveData = response.asLiveData()
assertEquals(movies, repoResponseAsLiveData.value)
}
}
結果は
java.lang.AssertionError:
Expected :[Movie(poster=https://image.tmdb.org/t/p/original/6Wdl9N6dL0Hi0T1qJLWSz6gMLbd.jpg, title=Mortal Kombat, rating=7.9, id=460465, rated=, duration=, genre=, releaseDate=, desc=, director=, writers=, stars=, creator=), Movie(poster=https://image.tmdb.org/t/p/original/pgqgaUx1cJb5oZQQ5v0tNARCeBp.jpg, title=Godzilla vs. Kong, rating=8.2, id=399566, rated=, duration=, genre=, releaseDate=, desc=, director=, writers=, stars=, creator=), Movie(poster=https://image.tmdb.org/t/p/original/oBgWY00bEFeZ9N25wWVyuQddbAo.jpg, title=Nobody, rating=8.5, id=615457, rated=, duration=, genre=, releaseDate=, desc=, director=, writers=, stars=, creator=), Movie(poster=https://image.tmdb.org/t/p/original/tnAuB8q5vv7Ax9UAEje5Xi4BXik.jpg, title=Zack Snyder's Justice League, rating=8.5, id=791373, rated=, duration=, genre=, releaseDate=, desc=, director=, writers=, stars=, creator=)]
Actual :null