RxJava 的模拟单元测试



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

他们使用ArgumentCaptor<TasksDataSource.GetTaskCallback>来触发带有虚假数据的回调COMPLETED_TASK

@Test 
fun getCompletedTaskFromRepositoryAndLoadIntoView() {
    presenter = TaskDetailPresenter(COMPLETED_TASK.id, tasksRepository, taskDetailView)
    presenter.start()
    // Then task is loaded from model, callback is captured
    verify(tasksRepository).getTask(
                eq(COMPLETED_TASK.id), capture(taskCallbackCaptor))
    // When task is finally loaded
    taskCallbackCaptor.value.onTaskLoaded(COMPLETED_TASK) // Trigger callback
}

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

fun getTask(taskId: String, callback: GetTaskCallback)

然后用作

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

但是当我尝试使用 RxJava Single<>而不是普通回调时,例如:

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

然后用作

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

然后我不能使用ArgumentCaptor<>来触发返回假数据。当我执行测试时,它总是抛出NullPointerException,因为tasksRepository.getTask(taskId)总是返回null

那么我怎样才能像谷歌一样实现相同的单元测试,但是在RxJava中呢?


我的单元测试代码:

@Mock private lateinit var tasksRepository: TasksRepository
@Captor private lateinit var taskCaptor: ArgumentCaptor<SingleObserver<Task>>
private lateinit var presenter: TaskDetailPresenter
@Before fun setup() {
    MockitoAnnotations.initMocks(this)
}
@Test 
fun getCompletedTaskFromRepositoryAndLoadIntoView() {
    presenter = TaskDetailPresenter(COMPLETED_TASK.id, tasksRepository, taskDetailView)
    presenter.start()
    // Then task is loaded from model, callback is captured
    verify(tasksRepository).getTask(
                eq(COMPLETED_TASK.id)).subscribe(taskCaptor.capture())
    // When task is finally loaded
    taskCaptor.value.onSuccess(COMPLETED_TASK) // Trigger callback
}

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

我不知道

你是否已经使用过这个库,但我建议你使用带有 MVP 代码架构的 Dagger 2 库,通过改进你的依赖关系和耦合来简化你的单元测试

这种方法所做的只是showTask(task:Task(。因此,断言此方法是在观察者开始观察后调用的。你不应该关心节目任务一旦被调用就会做什么。如果使用 Rx,最好让你的方法接受观察模式的参数和返回值,以便更容易编写单元测试。

相关内容

  • 没有找到相关文章

最新更新