3

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
}
4

1 に答える 1