【问题标题】:Unit testing with RxJava2 and MutableLiveData使用 RxJava2 和 MutableLiveData 进行单元测试
【发布时间】:2018-11-15 02:44:16
【问题描述】:

我正在尝试对一些使用 RxJava2 的 Android/Kotlin 代码进行单元测试。代码大致如下:

val temperature = MutableLiveData<Double>()

fun save(): Single<Result<ClassifyResponse>> {
    val temp = temperature.value
    ...
    return repository.classify(request)
        .flatMap { response->
                val result: Result<ClassifyResponse> = Result.Success(response)
                Single.just(result)
        }.onErrorReturn {
                Result.Error(it)
        }
}

但是,我收到以下异常:

java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.

每次我运行我的单元测试。我阅读了很多tutorialsSO answers,但即使在使用了 RxJavaPlugins 之后,我似乎仍然无法模拟主线程调度程序并且同样的异常盛行。

有人可以看看我的单元测试课程并建议我在这里缺少什么吗?

class MyViewModelTest() {

    private val repository = mock(MyRepository::class.java)

    private val immediateScheduler = object : Scheduler() {
        override fun createWorker(): Worker {
            return ExecutorScheduler.ExecutorWorker(Executor { it.run() })
        }
    }

    @Before
    fun setUp() {
        RxJavaPlugins.setInitIoSchedulerHandler { immediateScheduler }
        RxJavaPlugins.setComputationSchedulerHandler { immediateScheduler }
        RxAndroidPlugins.setInitMainThreadSchedulerHandler { immediateScheduler }
        RxAndroidPlugins.setInitMainThreadSchedulerHandler { immediateScheduler }
    }

    @Test
    fun test() {
        // given temperature view model
        val viewModel = MyViewModel(repository)
        ...

        val classifyResponse = ClassifyResponse(...)
        `when`(repository.classify(any(ClassifyRequest::class.java))).then { Single.just(classifyResponse) }

        // when sending request
        val result = viewModel.save()

        // then verify result
        val expected = Result.success(classifyResponse)

        assertEquals(expected, result)
    }
}

编辑:我注意到它由于使用MutableLiveData 而失败。当我尝试访问 temperature.value 时,它抱怨 MainLooper 线程。

【问题讨论】:

  • 您的测试似乎一切正常。你能再展示一些代码,尤其是那些与线程混在一起的代码吗?
  • 我刚刚注意到它是由在我的 viewModel(和测试)中使用 MutableLiveData 引起的。是否也有任何解决方法?

标签: android unit-testing junit kotlin rx-java2


【解决方案1】:

您的 RxJava 配置正确,为了测试 MutableLiveData,您需要在测试中设置规则:

@Rule
@JvmField
val rule = InstantTaskExecutorRule()

其中InstantTaskExecutorRule 来自模块android.arch.core:core-testing(即将移至AndroidX)- 目前最新版本是1.1.1。

【讨论】:

    猜你喜欢
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 2011-02-20
    • 2015-09-16
    • 2015-09-01
    • 2014-12-25
    • 1970-01-01
    相关资源
    最近更新 更多