简体   繁体   English

Robolectric测试和LiveData

[英]Robolectric test and LiveData

To get a hang of Kotlin, LiveData and Robolectric alltogether, I got a simple splash screen activity. 为了完全了解Kotlin,LiveData和Robolectric,我得到了一个简单的启动画面活动。

It works properly when running the application, but it fails to work in the test. 它在运行应用程序时正常工作,但无法在测试中工作。 It is like the live data's callback is never triggered or like if no oberver is registered for it. 就像实时数据的回调永远不会被触发一样,或者就像没有为它注册的oberver一样。

Here is the test: 这是测试:

@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)
}

The activity: 活动:

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()
        }
    }
}

The view model (which gets mocked anyway, so implementation is not used): 视图模型(无论如何都会被模拟,因此不使用实现):

/**
 * 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
}

It looks like Robolectric is not triggering the Android Lifecycle methods, so LiveData will not update observers. 看起来Robolectric没有触发Android生命周期方法,因此LiveData不会更新观察者。 I was able to fix this by manually triggering the "ON_START" Lifecycle event after the activity was created by Robolectric: 我能够通过在Robolectric创建活动后手动触发“ON_START”生命周期事件来解决这个问题:

activity.lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM