所以我有一个简单的测试,我尝试测试错误结果,如下所示:
@Test
fun `test`() {
every { Util.fetchLocation()} returns Single.error(Exception())
val resultErrors = testableClass.testableFun().test().errors()
Assert.assertTrue(resultErrors.size == 1)
Assert.assertTrue(resultErrors.firstOrNull() is Exception)
}
在 testableClass 内部调用一个方法,我嘲笑了它。 问题是,在这个类中,我必须将 RxJava Single 映射到挂起乐趣,然后将挂起乐趣映射到 Single<> ,如下所示:
private suspend fun getString(): String{
return "string"
}
private fun getIntAsSingle(): Single<Int> {
return Single.just(2)
}
private suspend fun mapSingleToSuspend(){
getIntAsSingle().await()
}
private suspend fun awesomeMethod(): String{
return getString() + mapSingleToSuspend().toString()
}
private fun mapSuspendToSingle(): Single<String>{
return rxSingle {
awesomeMethod()
}
}
rxSingle 方法来自 kotlinx.coroutines.rx2 库
没有其他方法可以做到这一点,因为我必须将第一个 suspend fun 的结果与第一个 Single 的结果一起使用,之后返回值必须是 Single<>
我认为,问题出在 RxJava wait 方法上,因为当我尝试调试测试时,测试结果触发的时间早于调用包含 wait() 方法的函数。
在测试类中,我在 RxJava 的 setUp() 方法中使用了它,但没有帮助:
RxAndroidPlugins.setMainThreadSchedulerHandler { Schedulers.trampoline() }
RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
为了测试,我使用 JUnit4 和模拟库。
尝试通行证调度程序:
internal class YorClassImpl @Inject constructor(
@IoDispatcher
private val ioDispatcher: CoroutineDispatcher,
) : YorClass {
//place where call rxSingle
rxSingle(ioDispatcher) { coroutineFun() }
}
你的测试看起来像:
private val testableClass = YourClassImpl(
ioDispatcher = UnconfinedTestDispatcher(),
)
@Test
fun `test`(): Unit = runTest(UnconfinedTestDispatcher()) {
every { Util.fetchLocation()} returns Single.error(Exception())
val resultErrors = testableClass.testableFun().test().errors()
Assert.assertTrue(resultErrors.size == 1)
Assert.assertTrue(resultErrors.firstOrNull() is Exception)
}