Robolectric测试与LiveData

3
为了学习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
}

我们遇到了同样的问题。你能解决它吗? - Emmanuel
1个回答

0

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

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

1
最新版本的Robolectric已经不再支持这个功能。 - slott
@slott,你有其他的解决方案吗? - Shawn
@Shawn 我目前正在研究使用这个第三方库:https://github.com/jraska/livedata-testing - slott
实际上,@Shawn,我发现有更好的东西。来自Google的LiveDataTestUtil运行良好,且实现起来更加容易。https://gist.github.com/JoseAlcerreca/1e9ee05dcdd6a6a6fa1cbfc125559bba - slott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接