在单元测试中无法从RxJava获得响应

问题描述

我试图在单元测试中获得RxJava2的响应,我找到了一个示例,但是我看不到和响应,可以帮我吗?谢谢。 该代码本身已经运行了很长时间,没有问题,当需要进行测试时,我遇到了一个问题,类似的示例或多或少是相同的,但是到处都是以这种方式完成的,但对我而言并不起作用。

有来自主持人的我的代码

  fun register(
    email: String,password: String,termsEnabled: Boolean,dayOfBirth: Int,monthOfBirth: Int,yearOfBirth: Int,formattedBirthDate: String,state: String?
) {
    adddisposable(
        registerUseCase.run(
            RegisterUseCase.RegisterRequest(
                email,password,termsEnabled,formattedBirthDate,state ?: ""
            )
        )
            .observeOn(mainThreadScheduler)
            .subscribeOn(backgroundScheduler)
            .subscribe(
                { 
                  getView?.showEmptyPassword()
                },{
                 getView?.showEmptyPassword()
                    }
            )
    )
}

并测试:

@Before
fun setUp() {
    RxAndroidplugins.setinitMainThreadSchedulerHandler { 
    Schedulers.trampoline() }
    MockitoAnnotations.initMocks(this)

    
    presenter = CreateAccountPresenter(
        mainThreadScheduler,backgroundScheduler,registerUseCase,getUserDataUseCase,getStatesUseCase,regexUtils,router,resourceUtils,deviceSharedPreferences
    )
    presenter.setView(view)
}


@Test
fun testRegister() {

    given(registerUseCase.run(RegisterUseCase.RegisterRequest(
        EMAIL,PASSWORD,true,FORMATTED_BIRTHDAY,STATE))
    ).willReturn(Single.just(RegisterResponse(false,"ok","id")))

    presenter.register(
        EMAIL,1,STATE)

    verify(view).showEmptyPassword()
}

但是问题是:

Wanted but not invoked:
view.showEmptyPassword();
-> at 
com.unikrn.esports.umode.CreateAccountPresenterTest.testRegister(CreateAccountPresenterTest.kt:179)
Actually,there were zero interactions with this mock.

解决方法

问题在于您正在后台线程中进行一些计算,即使被嘲笑,也没有足够的时间来完成verify调用

由于您已经为操作注入了调度程序,因此请指定它们均为trampoline,以便所有内容都在同一线程中运行

@Before
fun setUp() {
    presenter = CreateAccountPresenter(
        Schedulers.trampoline(),Schedulers.trampoline(),...
    )
}

在最坏的情况下,您可以添加一些阻止测试执行的blocker元素(例如Semaphore),然后在您的view方法之一中将其释放(需要进行存根) )

根据文档,Schedulers.trampoline()计划当前线程中的所有任务,因此一切都会被阻塞。如果您想直接使用某些调度程序,例如Schedulers.io(),则需要以与现在使用的类似方式覆盖它们

RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() } // Override MainThreadScheduler

请注意,上一片段只是一个示例,您需要对其进行调整