RxJava的模拟单元测试

时间:2019-06-01 18:39:27

标签: android unit-testing mockito rx-java android-testing

我正在根据Google的示例为我的应用编写单元测试:TaskDetailPresenterTest.kt#L102

在此示例中,他们使用ArgumentCaptor<TasksDataSource.GetTaskCallback> 触发带有伪数据COMPLETED_TASK的回调

@Test 
fun getCompletedTaskFromRepositoryAndLoadIntoView() {
    taskDetailPresenter = TaskDetailPresenter(COMPLETED_TASK.id, tasksRepository, taskDetailView)
    taskDetailPresenter.start()

    // Then task is loaded from model, callback is captured
    verify(tasksRepository).getTask(
                eq(COMPLETED_TASK.id), capture(getTaskCallbackCaptor))

    // When task is finally loaded
    getTaskCallbackCaptor.value.onTaskLoaded(COMPLETED_TASK) // Trigger callback
}

一切正常,因为它们使用TasksDataSource.GetTaskCallback返回数据。参见:TaskDetailPresenter.kt#L36

fun getTask(taskId: String, callback: GetTaskCallback)

然后用作

override fun start() {
    openTask()
}

private fun openTask() {
    tasksRepository.getTask(taskId, object : TasksDataSource.GetTaskCallback {
        override fun onTaskLoaded(task: Task) {
            showTask(task)
        }
    }
}

但是当我尝试使用 RxJava Single <>代替常规回调时,例如:

fun getTask(taskId: String): Single<Task>

然后用作

private fun openTask() {
    tasksRepository.getTask(taskId)
            .subscribe(object : SingleObserver<Task> {
                override fun onSuccess(task: Task) {
                    showTask(task)
                }

                override fun onError(e: Throwable) {
                }
            })
    }
}

然后,我无法使用ArgumentCaptor<>触发返回假数据。由于tasksRepository.getTask(taskId)总是 ,因此返回null

那么如何才能在RxJava中实现与Google相同的单元测试?


我的单元测试代码:

@Mock private lateinit var tasksRepository: TasksRepository

@Captor private lateinit var getTaskCallbackCaptor:
            ArgumentCaptor<TasksDataSource.GetTaskCallback>

private lateinit var taskDetailPresenter: TaskDetailPresenter

@Before fun setup() {
    MockitoAnnotations.initMocks(this)
}

@Test 
fun getCompletedTaskFromRepositoryAndLoadIntoView() {
    taskDetailPresenter = TaskDetailPresenter(COMPLETED_TASK.id, tasksRepository, taskDetailView)
    taskDetailPresenter.start()

    // Then task is loaded from model, callback is captured
    verify(tasksRepository).getTask(
                eq(COMPLETED_TASK.id)).subscribe(getTaskCallbackCaptor.capture())

    // When task is finally loaded
    getTaskCallbackCaptor.value.onSuccess(COMPLETED_TASK) // Trigger callback
}

请注意,所有其他部分(声明,设置,模拟等)与Google相同。

2 个答案:

答案 0 :(得分:0)

我不知道您是否已经使用过该库,但是我建议您使用具有MVP代码架构的Dagger 2库,以通过改善依赖关系和耦合来简化单元测试

答案 1 :(得分:0)

此方法所做的全部是showTask(task:Task)。因此断言在观察者开始观察之后将调用此方法。您不必担心showTask调用后将要做什么。如果使用Rx,最好使您的方法接受参数并返回观察模式的值,以使编写单元测试更加容易。