Spek + Retrofit api测试崩溃

时间:2018-04-26 13:55:29

标签: android kotlin retrofit2 rx-java2 spek

我正在尝试使用Spek测试Retrofit api

它会在 on {...} 块上抛出nullPointerException

相关的堆栈跟踪:https://pastebin.com/gy6dLtGg

这是我的测试类

@RunWith(JUnitPlatform::class)
class AccountCheckViewModelTest : Spek({

    include(RxSchedulersOverrideRule)

    val httpException = mock<HttpException> {
        on { code() }.thenReturn(400)
    }

    given(" account check view model") {
        var accountCheckRequest = mock<CheckExistingAccountRequest>()
        var accountCheckResponse = mock<CheckExistingAccountResponse>()
        var webService = mock<IAPICalls>()

        val accountCheckViewModel = spy(VMAccountCheck(webService))

        beforeEachTest {
            accountCheckRequest = mock<CheckExistingAccountRequest>() {
                on { email }.thenReturn("foo@mail")
            }

            accountCheckResponse = mock<CheckExistingAccountResponse>() {
                on { firstName }.thenReturn("foo")
                on { email }.thenReturn("foo@mail")
            }

            webService = mock<IAPICalls> {
                on { checkExistingAccount(accountCheckRequest) }.thenReturn(Flowable.just(accountCheckResponse))
            }
         }
        on("api success") {
            accountCheckViewModel.checkIfAccountExists(request = accountCheckRequest)

            it("should call live data with first name as foo") {
               verify(accountCheckViewModel, times(1)).updateLiveData(accountCheckResponse.firstName, accountCheckResponse.email, null)
            }
        }
    }
}

这是我的RxSchedulersOverrideSpek类

 class RxSchedulersOverrideSpek : Spek({

    beforeGroup {
        RxJavaPlugins.onIoScheduler(Schedulers.trampoline())
        RxJavaPlugins.onComputationScheduler(Schedulers.trampoline())
        RxJavaPlugins.onNewThreadScheduler(Schedulers.trampoline())
    }
})

2 个答案:

答案 0 :(得分:1)

您应该使用memoized来正确设置测试值。问题是accountCheckViewModel在Spek的发现阶段初始化,传递给webService的{​​{1}}模拟是该点的值(你没有模拟它的任何方法) 。 accountCheckViewModel在执行阶段运行,您已在此处重新分配beforeEachTest到正确的模拟,但webService仍保留以前的值。

accountCheckViewModel

答案 1 :(得分:0)

假设您将 RxJava2 RxAndroid 一起使用,则应使用Schedulers.trampoline()覆盖RxAndroid调度程序。这样,所有在trampoline()上订阅的作业都将在同一个帖子中逐个排队并执行。

RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }

您的RxSchedulersOverrideSpek.kt应如下所示:

object RxSchedulersOverrideSpek : Spek({

    beforeGroup {
        RxJavaPlugins.onIoScheduler(Schedulers.trampoline())
        RxJavaPlugins.onComputationScheduler(Schedulers.trampoline())
        RxJavaPlugins.onNewThreadScheduler(Schedulers.trampoline())
        RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
    }

    afterGroup {
        RxJavaPlugins.reset()
        RxAndroidPlugins.reset()
    }
})