如何解决测试RxJava重复时带Mockk返回很多
我正在尝试使用Mockk库测试多个服务器响应。就像我在this answer中找到的Mockito一样。
我有一个示例UseCase代码,每隔几秒钟重复一次从远程服务器加载系统的调用,并且当远程系统包含的用户多于本地用户时,它将停止运行(onComplete
)。
override fun execute(localSystem: System,delay: Long): Completable {
return cloudRepository.getSystem(localSystem.id)
.repeatWhen { repeatHandler -> // Repeat every [delay] seconds
repeatHandler.delay(params.delay,TimeUnit.SECONDS)
}
.takeUntil { // Repeat until remote count of users is greater than local count
return@takeUntil it.users.count() > localSystem.users.count()
}
.ignoreElements() // Ignore onNext() calls and wait for onComplete()/onError() call
}
要测试此行为,我在Mockk库中模拟cloudRepository.getSystem()
方法:
@Test
fun testListeningEnds() {
every { getSystem(TEST_SYSTEM_ID) } returnsMany listOf(
Single.just(testSystemGetResponse),// return the same amount of users as local system has
Single.just(testSystemGetResponse),// return the same amount of users as local system has
Single.just( // return the greater amount of users as local system has
testSystemGetResponse.copy(
owners = listOf(
TEST_USER,TEST_USER.copy(id = UUID.randomUUID().toString())
)
)
)
)
useCase.execute(
localSystem = TEST_SYSTEM,delay = 3L
)
.test()
.await()
.assertComplete()
}
如您所见,我正在使用returnsMany
答案,该答案应在每次通话时返回不同的值。
主要问题是returnsMany
每次都返回相同的第一个值,而.takeUntil {}
永不成功,这意味着从未为该Completable调用onComplete()
。如何使returnsMany
在每次通话中返回不同的值?
解决方法
您可能不了解.repeatWhen()
的工作原理。您希望每次请求重复时都会调用cloudRepository.getSystem(id)
。那是不对的。重复预订始终在模拟Single
的同一实例上进行–在您的情况下,第一个Single.just(testSystemGetResponse)
。
如何确保getSystem()
每次都被调用?将您的Single包装到Single.defer()
中。它类似于Single.fromCallable()
,但是所传递的lambda的返回类型之间存在差异。传递给.defer()
运算符的Lambda必须返回Rx类型(在本例中为Single)。
最终实现(我进行了一些更改以使其能够成功编译):
data class User(val id: String)
data class System(val users: List<User>,val id: Long)
class CloudRepository {
fun getSystem(id: Long) = Single.just(System(mutableListOf(),id))
}
class SO63506574(
private val cloudRepository: CloudRepository
) {
fun execute(localSystem: System,delay: Long): Completable {
return Single.defer { cloudRepository.getSystem(localSystem.id) } // <-- defer
.repeatWhen { repeatHandler ->
repeatHandler.delay(delay,TimeUnit.SECONDS)
}
.takeUntil {
return@takeUntil it.users.count() > localSystem.users.count()
}
.ignoreElements()
}
}
并测试(约8秒后成功):
class SO63506574Test {
@Test
fun testListeningEnds() {
val TEST_USER = User("UUID")
val TEST_SYSTEM = System(mutableListOf(),10)
val repository = mockk<CloudRepository>()
val useCase = SO63506574(repository)
val testSystemGetResponse = System(mutableListOf(),10)
every { repository.getSystem(10) } returnsMany listOf(
Single.just(testSystemGetResponse),// return the same amount of users as local system has
Single.just(testSystemGetResponse),// return the same amount of users as local system has
Single.just( // return the greater amount of users as local system has
testSystemGetResponse.copy(
users = listOf(
TEST_USER,TEST_USER.copy(id = UUID.randomUUID().toString())
)
)
)
)
useCase.execute(
localSystem = TEST_SYSTEM,delay = 3L
)
.test()
.await()
.assertComplete()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。