为了同时掌握 Kotlin、LiveData 和 Robolectric,我做了一个简单的闪屏活动。
它在运行应用程序时可以正常工作,但在测试中无法正常工作。这就像实时数据的回调永远不会被触发,或者就像没有为其注册观察者一样。
这是测试:
@Test
fun should_redirect_to_login_when_time_is_up_after_onStart() {
val timeUp = MutableLiveData<Boolean>()
kodein.addConfig {
bind<SplashViewModel>(overrides = true) with factory {
_: BaseActivity -> mock<SplashViewModel> { on { isTimeUp() } doReturn timeUp }
}
}
val activity = Robolectric.buildActivity(SplashActivity::class.java).create().start().resume().get()
timeUp.value = true
val startedIntent = shadowOf(activity).nextStartedActivity
assertThat(startedIntent).isNotNull
assertThat(startedIntent).hasComponent(application.packageName, LoginActivity::class.java)
}
活动:
class SplashActivity : JapetActivity() {
lateinit var viewModel: SplashViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
viewModel = kodein.with(this).instance()
viewModel.isTimeUp().observe(this, Observer<Boolean?> { b -> transitionIfTimeUp(b ?: false) })
transitionIfTimeUp(viewModel.isTimeUp().value ?: false)
}
private fun transitionIfTimeUp(isTimeUp: Boolean) {
if (isTimeUp) {
startActivity(Intent(this, LoginActivity::class.java))
finish()
}
}
}
视图模型(无论如何都会被嘲笑,因此不使用实现):
/**
* ViewModel for data of the splash screen
*/
interface SplashViewModel {
/** Have we shown the splash screen long enough? */
fun isTimeUp(): LiveData<Boolean>
}
/**
* Default implementation of the view model
*/
class SplashViewModelImpl : ViewModel(), SplashViewModel {
companion object {
private const val SPLASH_DURATION_MS = 2000L
}
private val isTimeUp = MutableLiveData<Boolean>()
init {
isTimeUp.value = false
Observable.timer(SplashViewModelImpl.SPLASH_DURATION_MS, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe { isTimeUp.value = true }
}
override fun isTimeUp(): LiveData<Boolean> = isTimeUp
}