Wenn Sie es normal machen, erhalten Sie "ExceptionInInitializerError" im Teil von "AndroidSchedulers.mainThread ()".
Dies liegt daran, dass der von `AndroidSchedulers.mainThread ()`
zurückgegebene Scheduler von Android abhängt. (Wenn Sie von Android abhängig sind, müssen Sie es in Android Test mit einem Emulator ausführen.)
Dies Link zur relevanten Quelle Ich werde.
Sie können dieses Problem umgehen, indem Sie es einfach als separaten Scheduler mit dem RxAndroidPlugins-Mechanismus initialisieren, bevor der Test ausgeführt wird.
Unten ist die Quelle von Kotlin. Verwenden Sie einfach den Plugin-Mechanismus, um eine TestRule zu definieren, die Ihren Scheduler nur von Android unabhängig macht.
RxImmediateSchedulerRule.kt
class RxImmediateSchedulerRule : TestRule {
private val immediate = object : Scheduler() {
override fun scheduleDirect(run: Runnable, delay: Long, unit: TimeUnit): Disposable {
return super.scheduleDirect(run, 0, unit)
}
override fun createWorker(): Worker {
return ExecutorScheduler.ExecutorWorker { it.run() }
}
}
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
RxJavaPlugins.setInitIoSchedulerHandler({ _ -> immediate })
RxJavaPlugins.setInitComputationSchedulerHandler({ _ -> immediate })
RxJavaPlugins.setInitNewThreadSchedulerHandler({ _ -> immediate })
RxJavaPlugins.setInitSingleSchedulerHandler({ _ -> immediate })
RxAndroidPlugins.setInitMainThreadSchedulerHandler({ _ -> immediate })
try {
base.evaluate()
} finally {
RxJavaPlugins.reset()
RxAndroidPlugins.reset()
}
}
}
}
}
Und machen Sie dies einfach vor dem Testen. Übrigens finden Sie in diesem Artikel den Grund, warum Sie `` `@ ClassRule``` nicht verwenden.
@RunWith(PowerMockRunner::class)
@PrepareForTest(Auth::class)
class LoginViewModelTest {
@Rule
val schedulers: RxImmediateSchedulerRule = RxImmediateSchedulerRule()
// companion object {
// @JvmField
// @ClassRule
// val schedulers: RxImmediateSchedulerRule = RxImmediateSchedulerRule()
// }
@Test
fun onClickLogin() {
val mockAuth = PowerMockito.mock(Auth::class.java)
val target = LoginViewModel(mockAuth)
target.mail.set("email")
target.password.set("password")
val result = Single.just(AuthEntity().apply {
accessToken = "123456"
userId = 100
})
PowerMockito.`when`(mockAuth.login("email", "password")).thenReturn(result)
target.onClickLogin().run()
Mockito.verify(mockAuth).login("email", "password")
}
}
Recommended Posts