为了学习Kotlin、LiveData和Robolectric的使用方法,我创建了一个简单的启动画面活动。在应用程序运行时它能够正常工作,但在测试中它无法工作。似乎LiveData的回调函数从未被触发,或者没有为其注册任何观察者。以下是测试代码:
视图模型(总是被模拟,因此实现不会被使用):
@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
}