Jos*_*llo 7 android unit-testing kotlin
我正在开发一个 Android 应用程序,我选择使用 Kotlin Result 类来处理我的操作的成功/失败。我对代码进行了更改,但测试停止工作,我不明白为什么。下面我给大家展示一些片段:
FireStoreClient.kt
suspend fun items(): Result<ItemsResponse>
Run Code Online (Sandbox Code Playgroud)
网络数据源.kt
suspend fun getItems(): List<Item> =
fireStoreClient.items().fold({ it.items.map { item -> item.toDomain() } }, { emptyList() })
Run Code Online (Sandbox Code Playgroud)
网络数据源测试.kt
@ExperimentalCoroutinesApi
@Test
fun `Check getItems works properly`() = runBlockingTest {
whenever(fireStoreClient.items()).doReturn(success(MOCK_ITEMS_DOCUMENT))
val expectedResult = listOf(
Item(
id = 1,
desc = "Description 1"
),
Item(
id = 2,
desc = "Description 2"
)
)
assertEquals(expectedResult, dataSource.getItems())
}
Run Code Online (Sandbox Code Playgroud)
这是我现在遇到的例外。有什么线索吗?单元测试时似乎未执行 Fold() 方法。
java.lang.ClassCastException: kotlin.Result cannot be cast to ItemsResponse
at NetworkDataSource.getItems(NetworkDataSource.kt:31)
Run Code Online (Sandbox Code Playgroud)
对于那些不想创建自己的Result
类型的人,我找到了解决此结果包装问题的不同解决方法。
这个问题似乎在使用 Mockito 的.thenReturn
onsuspend
函数时特别发生。我发现使用.thenAnswer
不会出现问题。
因此,不要在单元测试中编写此内容(更改doReturn
为thenReturn
此处):
whenever(fireStoreClient.items()).thenReturn(success(MOCK_ITEMS_DOCUMENT))
Run Code Online (Sandbox Code Playgroud)
使用:
whenever(fireStoreClient.items()).thenAnswer { success(MOCK_ITEMS_DOCUMENT) }
Run Code Online (Sandbox Code Playgroud)
编辑:我应该注意到,在运行 Kotlin 1.5.0 时我仍然遇到这个问题。
编辑:在 Kotlin 1.5.20 上我可以.thenReturn
再次使用。
我遇到过同样的问题。
我注意到我应该返回的注入类的方法Result<List<Any>>
实际上返回了Result<Result<List<Any>>>
,这导致了ClassCastException
. 我使用了Evaluate Expression
该方法的结果选项,我得到了
Success(Success([]))
Run Code Online (Sandbox Code Playgroud)
该应用程序运行良好,但由于此问题,单元测试未通过。
作为临时解决方案,我构建了一个Result
具有扩展功能的密封类的新简单实现fold()
。以后应该很容易更换kotlin.Result
Result
密封等级:
sealed class Result<T> {
data class Success<T>(val value: T) : Result<T>()
data class Failure<T>(val error: Throwable) : Result<T>()
}
Run Code Online (Sandbox Code Playgroud)
fold()
扩展功能:
inline fun <R, T> Result<T>.fold(
onSuccess: (value: T) -> R,
onFailure: (exception: Throwable) -> R
): R = when (this) {
is Result.Success -> onSuccess(value)
is Result.Failure -> onFailure(error)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5927 次 |
最近记录: |