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

Android 在单元测试中无法从RxJava获取响应,android,unit-testing,mockito,rx-java,rx-java2,Android,Unit Testing,Mockito,Rx Java,Rx Java2,在单元测试中,我试图从RxJava2获得响应,我找到了一个例子,但是我看不到和响应,你能帮我吗?非常感谢。 代码本身已经工作了很长一段时间,没有问题,当需要测试时,我遇到了一个问题,类似的例子或多或少都是一样的,但无论在哪里都是这样做的,但对我来说不起作用 这是演示者提供的我的代码: fun register( email: String, password: String, termsEnabled: Boolean, dayOfBirth: Int,

在单元测试中,我试图从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,
        PASSWORD,
        true,
        1,
        1,
        1,
        FORMATTED_BIRTHDAY,
        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(),
        ...
    )
}
在最坏的情况下,您可以添加一些阻止测试执行的阻止器元素(例如
信号量
),然后在
视图
方法中释放它(您需要使用stub)

根据文档,安排当前线程中的所有任务,以便所有任务都被阻塞。如果您想直接使用一些调度器,如
schedulers.io()
,您需要以与现在使用的类似的方式覆盖它们

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

请注意,前面的代码片段只是一个示例,您需要对其进行修改

是否可以包含用于创建测试演示者的代码?我打赌你在幕后操纵一切。虽然它适用于应用程序,但它不适用于测试(需要阻塞)是的,我尝试在代码和测试中设置延迟,什么都没有help@Pelocho我认为你是对的,但是如何修复它呢?)是的,它是有效的,谢谢你,但是你能解释为什么吗?Schedulers.trampoline()是什么?如果我只使用.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())它将无法工作?为什么?既然你已经在你的代码中使用了它,我假设你知道它是什么以及它是如何工作的。我会在回答中添加一些解释。一位老开发人员创建了一个项目,我可以使用它,但我不知道他为什么这么做,这就是我回答的原因。我建议你看一下该项目的官方文档。否则,您将面临一些问题,而这些问题可以通过不犯一些愚蠢的错误来轻松避免