-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from azrael8576/test/unit-test
Add Unit tests PixabayImagePagingSourceTest
- Loading branch information
Showing
12 changed files
with
1,412 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"total": 7, | ||
"totalHits": 7, | ||
"hits": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
{ | ||
"total": 3, | ||
"totalHits": 3, | ||
"hits": [ | ||
{ | ||
"id": 26451, | ||
"pageURL": "https://pixabay.com/videos/id-26451/", | ||
"type": "film", | ||
"tags": "cat, happy, animal", | ||
"duration": 13, | ||
"picture_id": "812497041-23341c0640e56f02b0026e5b218ed3d904c28c2659fc45b01f955081ae5bcf59-d", | ||
"videos": { | ||
"large": { | ||
"url": "https://cdn.pixabay.com/vimeo/358778852/cat-26451.mp4?width=1920&hash=c8cdad290d1a1f4769d27507dd118d5fa516c4d8", | ||
"width": 1920, | ||
"height": 1080, | ||
"size": 4880942 | ||
}, | ||
"medium": { | ||
"url": "https://cdn.pixabay.com/vimeo/358778852/cat-26451.mp4?width=1280&hash=3881821c4ebfbcff7ad26565e0e7d4799d89489a", | ||
"width": 1280, | ||
"height": 720, | ||
"size": 2400471 | ||
}, | ||
"small": { | ||
"url": "https://cdn.pixabay.com/vimeo/358778852/cat-26451.mp4?width=960&hash=7c54108fa571d78b323b9354b13b0e2bb22f265a", | ||
"width": 960, | ||
"height": 540, | ||
"size": 1606121 | ||
}, | ||
"tiny": { | ||
"url": "https://cdn.pixabay.com/vimeo/358778852/cat-26451.mp4?width=640&hash=e31e3b41a6c9e838e934bfa9bcfc6c8d4686cf34", | ||
"width": 640, | ||
"height": 360, | ||
"size": 671151 | ||
} | ||
}, | ||
"views": 24055, | ||
"downloads": 9349, | ||
"likes": 92, | ||
"comments": 20, | ||
"user_id": 13034296, | ||
"user": "talipozer", | ||
"userImageURL": "" | ||
}, | ||
{ | ||
"id": 2911, | ||
"pageURL": "https://pixabay.com/videos/id-2911/", | ||
"type": "film", | ||
"tags": "cat, cats, lazy", | ||
"duration": 20, | ||
"picture_id": "568296387-20dc5252018653569acaab9576e70bc7c7e407eb9497db84db1f0a221c39e32d-d", | ||
"videos": { | ||
"large": { | ||
"url": "https://cdn.pixabay.com/vimeo/164639743/cat-2911.mp4?width=1920&hash=ea47340c69dce271c915bf2bc6bb5efef3da797c", | ||
"width": 1920, | ||
"height": 1080, | ||
"size": 11063802 | ||
}, | ||
"medium": { | ||
"url": "https://cdn.pixabay.com/vimeo/164639743/cat-2911.mp4?width=1280&hash=438c8c8033af16e66a03c9236957e0ab82ccebea", | ||
"width": 1280, | ||
"height": 720, | ||
"size": 6160427 | ||
}, | ||
"small": { | ||
"url": "https://cdn.pixabay.com/vimeo/164639743/cat-2911.mp4?width=960&hash=75923149aa3c2e036435aa17abc45912a26cfa94", | ||
"width": 960, | ||
"height": 540, | ||
"size": 3572267 | ||
}, | ||
"tiny": { | ||
"url": "https://cdn.pixabay.com/vimeo/164639743/cat-2911.mp4?width=640&hash=e0685c1462618d5573e047d85022acbba86d8aa1", | ||
"width": 640, | ||
"height": 360, | ||
"size": 1219438 | ||
} | ||
}, | ||
"views": 18617, | ||
"downloads": 10409, | ||
"likes": 104, | ||
"comments": 26, | ||
"user_id": 1, | ||
"user": "Pixabay", | ||
"userImageURL": "https://cdn.pixabay.com/user/2014/10/13/11-29-23-818_250x250.png" | ||
}, | ||
{ | ||
"id": 143654, | ||
"pageURL": "https://pixabay.com/videos/id-143654/", | ||
"type": "film", | ||
"tags": "cat, kitten, stray cat", | ||
"duration": 77, | ||
"picture_id": "1574564044-6813360a2af587b3a9fbb58ec9497fd15f06a189129c18e044f52715eacf6ef0-d", | ||
"videos": { | ||
"large": { | ||
"url": "https://cdn.pixabay.com/vimeo/784129635/cat-143654.mp4?width=1920&hash=b4f0f888802678d03b66ae5c7d0ed846314b88ab", | ||
"width": 1920, | ||
"height": 1080, | ||
"size": 54308977 | ||
}, | ||
"medium": { | ||
"url": "https://cdn.pixabay.com/vimeo/784129635/cat-143654.mp4?width=1280&hash=5cbce9ea3870804760bc923b0d3bfc33410f5a67", | ||
"width": 1280, | ||
"height": 720, | ||
"size": 27164139 | ||
}, | ||
"small": { | ||
"url": "https://cdn.pixabay.com/vimeo/784129635/cat-143654.mp4?width=960&hash=cc246ba7a09e075df9f8df0a0a0812faafcb7fa8", | ||
"width": 960, | ||
"height": 540, | ||
"size": 16116099 | ||
}, | ||
"tiny": { | ||
"url": "https://cdn.pixabay.com/vimeo/784129635/cat-143654.mp4?width=640&hash=e67bcab20be8278476ff35b83240c96401185701", | ||
"width": 640, | ||
"height": 360, | ||
"size": 7567345 | ||
} | ||
}, | ||
"views": 1988, | ||
"downloads": 1096, | ||
"likes": 29, | ||
"comments": 1, | ||
"user_id": 26479159, | ||
"user": "colorful_square", | ||
"userImageURL": "https://cdn.pixabay.com/user/2022/09/23/04-26-24-253_250x250.jpg" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"total": 3, | ||
"totalHits": 3, | ||
"hits": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import androidx.annotation.VisibleForTesting | ||
import com.wei.picquest.core.network.fake.FakeAssetManager | ||
import java.io.File | ||
import java.io.InputStream | ||
import java.util.Properties | ||
|
||
/** | ||
* This class helps with loading Android `/assets` files, especially when running JVM unit tests. | ||
* It must remain on the root package for an easier [Class.getResource] with relative paths. | ||
* @see <a href="https://developer.android.com/reference/tools/gradle-api/7.3/com/android/build/api/dsl/UnitTestOptions">UnitTestOptions</a> | ||
*/ | ||
@VisibleForTesting | ||
internal object JvmUnitTestFakeAssetManager : FakeAssetManager { | ||
private val config = | ||
requireNotNull(javaClass.getResource("com/android/tools/test_config.properties")) { | ||
""" | ||
Missing Android resources properties file. | ||
Did you forget to enable the feature in the gradle build file? | ||
android.testOptions.unitTests.isIncludeAndroidResources = true | ||
""".trimIndent() | ||
} | ||
private val properties = Properties().apply { config.openStream().use(::load) } | ||
private val assets = File(properties["android_merged_assets"].toString()) | ||
|
||
override fun open(fileName: String): InputStream = File(assets, fileName).inputStream() | ||
} |
7 changes: 7 additions & 0 deletions
7
core/network/src/main/java/com/wei/picquest/core/network/fake/FakeAssetManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.wei.picquest.core.network.fake | ||
|
||
import java.io.InputStream | ||
|
||
fun interface FakeAssetManager { | ||
fun open(fileName: String): InputStream | ||
} |
71 changes: 71 additions & 0 deletions
71
core/network/src/main/java/com/wei/picquest/core/network/fake/FakePqNetworkDataSource.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.wei.picquest.core.network.fake | ||
|
||
import JvmUnitTestFakeAssetManager | ||
import com.wei.picquest.core.network.Dispatcher | ||
import com.wei.picquest.core.network.PqDispatchers | ||
import com.wei.picquest.core.network.PqNetworkDataSource | ||
import com.wei.picquest.core.network.model.NetworkSearchImages | ||
import com.wei.picquest.core.network.model.NetworkSearchVideos | ||
import kotlinx.coroutines.CoroutineDispatcher | ||
import kotlinx.coroutines.withContext | ||
import kotlinx.serialization.ExperimentalSerializationApi | ||
import kotlinx.serialization.json.Json | ||
import kotlinx.serialization.json.decodeFromStream | ||
import org.jetbrains.annotations.VisibleForTesting | ||
|
||
class FakePqNetworkDataSource( | ||
@Dispatcher(PqDispatchers.IO) private val ioDispatcher: CoroutineDispatcher, | ||
private val networkJson: Json, | ||
private val assets: FakeAssetManager = JvmUnitTestFakeAssetManager, | ||
) : PqNetworkDataSource { | ||
|
||
private var shouldReturnErrorForImages = false | ||
private var shouldReturnErrorForVideos = false | ||
|
||
@VisibleForTesting | ||
fun setReturnErrorForImages(shouldReturnError: Boolean) { | ||
shouldReturnErrorForImages = shouldReturnError | ||
} | ||
|
||
@VisibleForTesting | ||
fun setReturnErrorForVideos(shouldReturnError: Boolean) { | ||
shouldReturnErrorForVideos = shouldReturnError | ||
} | ||
|
||
@OptIn(ExperimentalSerializationApi::class) | ||
override suspend fun searchImages(query: String, page: Int, perPage: Int): NetworkSearchImages = | ||
withContext(ioDispatcher) { | ||
if (shouldReturnErrorForImages) { | ||
throw Exception("Fake exception for images") | ||
} | ||
when (page) { | ||
0 -> assets.open(IMAGES_PAGE1_ASSET).use(networkJson::decodeFromStream) | ||
1 -> assets.open(IMAGES_PAGE2_ASSET).use(networkJson::decodeFromStream) | ||
else -> { | ||
assets.open(IMAGES_PAGE_END_ASSET).use(networkJson::decodeFromStream) | ||
} | ||
} | ||
} | ||
|
||
@OptIn(ExperimentalSerializationApi::class) | ||
override suspend fun searchVideos(query: String, page: Int, perPage: Int): NetworkSearchVideos = | ||
withContext(ioDispatcher) { | ||
if (shouldReturnErrorForVideos) { | ||
throw Exception("Fake exception for images") | ||
} | ||
when (page) { | ||
0 -> assets.open(VIDEOS_PAGE1_ASSET).use(networkJson::decodeFromStream) | ||
else -> { | ||
assets.open(VIDEOS_PAGE_END_ASSET).use(networkJson::decodeFromStream) | ||
} | ||
} | ||
} | ||
|
||
companion object { | ||
private const val IMAGES_PAGE1_ASSET = "images_page1.json" | ||
private const val IMAGES_PAGE2_ASSET = "images_page2.json" | ||
private const val IMAGES_PAGE_END_ASSET = "images_page_end.json" | ||
private const val VIDEOS_PAGE1_ASSET = "videos_page1.json" | ||
private const val VIDEOS_PAGE_END_ASSET = "videos_page_end.json" | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
.../src/test/java/com/wei/picquest/core/network/pagingsource/PixabayImagePagingSourceTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package com.wei.picquest.core.network.pagingsource | ||
|
||
import JvmUnitTestFakeAssetManager | ||
import androidx.paging.PagingSource | ||
import com.google.common.truth.Truth.assertThat | ||
import com.wei.picquest.core.network.fake.FakePqNetworkDataSource | ||
import kotlinx.coroutines.test.StandardTestDispatcher | ||
import kotlinx.coroutines.test.runTest | ||
import kotlinx.serialization.json.Json | ||
import org.junit.Before | ||
import org.junit.Test | ||
|
||
/** | ||
* Unit tests for [PixabayImagePagingSource]. | ||
* | ||
* 遵循此模型,安排、操作、斷言: | ||
* {Arrange}{Act}{Assert} | ||
*/ | ||
class PixabayImagePagingSourceTest { | ||
|
||
private lateinit var fakePqNetworkDataSource: FakePqNetworkDataSource | ||
private lateinit var pixabayImagePagingSource: PixabayImagePagingSource | ||
|
||
private val testDispatcher = StandardTestDispatcher() | ||
|
||
@Before | ||
fun setUp() { | ||
fakePqNetworkDataSource = FakePqNetworkDataSource( | ||
ioDispatcher = testDispatcher, | ||
networkJson = Json { ignoreUnknownKeys = true }, | ||
assets = JvmUnitTestFakeAssetManager, | ||
) | ||
pixabayImagePagingSource = PixabayImagePagingSource(fakePqNetworkDataSource, "testQuery") | ||
} | ||
|
||
@Test | ||
fun `load should return non-empty page for first and second page`() = runTest(testDispatcher) { | ||
// Arrange | ||
val firstPageKey = 0 | ||
val secondPageKey = 1 | ||
|
||
// Act | ||
val firstPageResult = pixabayImagePagingSource.load( | ||
PagingSource.LoadParams.Refresh( | ||
key = firstPageKey, | ||
loadSize = 20, | ||
placeholdersEnabled = false, | ||
), | ||
) | ||
val secondPageResult = pixabayImagePagingSource.load( | ||
PagingSource.LoadParams.Refresh( | ||
key = secondPageKey, | ||
loadSize = 20, | ||
placeholdersEnabled = false, | ||
), | ||
) | ||
|
||
// Assert | ||
assertThat(firstPageResult).isInstanceOf(PagingSource.LoadResult.Page::class.java) | ||
assertThat((firstPageResult as PagingSource.LoadResult.Page).data).isNotEmpty() | ||
assertThat(secondPageResult).isInstanceOf(PagingSource.LoadResult.Page::class.java) | ||
assertThat((secondPageResult as PagingSource.LoadResult.Page).data).isNotEmpty() | ||
} | ||
|
||
@Test | ||
fun `load should return empty page at end of pagination`() = runTest(testDispatcher) { | ||
// Arrange | ||
val endPageKey = 2 // Assuming this is the end | ||
|
||
// Act | ||
val endPageResult = pixabayImagePagingSource.load( | ||
PagingSource.LoadParams.Refresh( | ||
key = endPageKey, | ||
loadSize = 20, | ||
placeholdersEnabled = false, | ||
), | ||
) | ||
|
||
// Assert | ||
assertThat(endPageResult).isInstanceOf(PagingSource.LoadResult.Page::class.java) | ||
assertThat((endPageResult as PagingSource.LoadResult.Page).data).isEmpty() | ||
} | ||
|
||
@Test | ||
fun `load should return error when data source throws exception`() = runTest { | ||
// Arrange | ||
fakePqNetworkDataSource.setReturnErrorForImages(true) | ||
|
||
// Act | ||
val result = pixabayImagePagingSource.load( | ||
PagingSource.LoadParams.Refresh( | ||
key = 0, | ||
loadSize = 20, | ||
placeholdersEnabled = false, | ||
), | ||
) | ||
|
||
// Assert | ||
assertThat(result).isInstanceOf(PagingSource.LoadResult.Error::class.java) | ||
} | ||
} |
Oops, something went wrong.