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

Can`t get response from RxJava in Unit test

我试图在单元测试中从 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(),
        ...
    )
}

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

根据文档,Schedulers.trampoline() 安排当前线程中的所有任务,因此一切都将被阻塞。如果你想直接使用像 Schedulers.io() 这样的调度程序,你需要以与

类似的方式覆盖它们
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() } // Override MainThreadScheduler

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