android - Robolectric 测试和 LiveData

标签 android testing kotlin robolectric android-livedata

为了全面掌握 Kotlin、LiveData 和 Robolectric,我进行了一个简单的启动画面 Activity 。

运行应用程序正常,但在测试中无法正常工作。这就像实时数据的回调永远不会被触发,或者如果没有观察者注册它。

这是测试:

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

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

View 模型(无论如何都会被模拟,所以不使用实现):

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

最佳答案

看起来 Robolectric 没有触发 Android 生命周期方法,所以 LiveData 不会更新观察者。在 Robolectric 创建 Activity 后,我可以通过手动触发“ON_START”生命周期事件来解决此问题:

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

关于android - Robolectric 测试和 LiveData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45054972/

相关文章:

php - 如何使用 phpunit_selenium2 扩展执行双击?

android - 从 kotlin 应用程序在 s3 上上传音频文件

kotlin - 如何在 Kotlin Multiplatform(纯 kotlin)中延迟

android - instanceId 和 getIdToken 有什么区别

java - 安卓Java : Linear Layout vanishes when placed on another Linear Layout

android - ListView 中的缩进

android - 单击时更改工具栏中的图标

php - Laravel 5.5 PHPUnit 不显示描述

testing - 使用 Ember 测试登录测试

java - 如何引入Android Context来测试?