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
}