Search code examples
androidunit-testingkotlinmockitorx-java2

Unit test have NullPointerException after calling function of presenter


such a problem, I check the request through RX with a test and then try to check the response, but in the response, if there was success, another method is also called with RX and there in the .observeOn (mainThreadScheduler) line I get java.lang.NullPointerException. The test itself is passed, how to remove the error? Thank you.

Function what i tested:

 fun login(email: String, password: String) {
    addDisposable(
        loginUseCase.run(
            LoginRequest(
                email,
                password,
                "en"
            )
        )
            .observeOn(mainThreadScheduler)
            .subscribeOn(backgroundScheduler)
            .subscribe(::onLoginSuccess, ::onLoginError)
    )
}
 private fun onLoginSuccess(loginResponse: LoginResponse) {
    with(loginResponse) {
        if (isError) {
            getView()?.showErrorMessage(message)
        } else {
            deviceSharedPreferences.setSessionId(sessionId)
            deviceSharedPreferences.setUserId(userId)
            getUserData()
        }
    }
}

Funcion that called when success and where i get NPE in .observeOn line

    override fun getUserData() {
    addDisposable(
        getUserDataUseCase.run()
            .observeOn(mainThreadScheduler)
            .subscribeOn(backgroundScheduler)
            .subscribe(this::onGetUserDataSuccess, Throwable::printStackTrace)
    )
}

Test:

  @Before
fun setUp() {
    presenter = LoginPresenter(
        Schedulers.trampoline(),
        Schedulers.trampoline(),
        loginUseCase,
        router,
        deviceSharedPreferences,
        getUserDataUseCase,
        resourceUtils,
        getUserProfileUseCase
    )
    presenter.setView(view)
}

    @Test
fun login() {

    given(loginUseCase.run(LoginUseCase.LoginRequest(USER_LOGIN, USER_PASSWORD,"en")))
        .willReturn(Single.just(LoginResponse(
            false,
        "ok",
        "id",
        "name",
        "userId")))

    presenter.login(USER_LOGIN, USER_PASSWORD)

    verify(deviceSharedPreferences,atLeastOnce()).setSessionId("id")

}

Error:

     java.lang.NullPointerException
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter.getUserData(LoginPresenter.kt:81)
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter.onLoginSuccess(LoginPresenter.kt:69)
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter.access$onLoginSuccess(LoginPresenter.kt:17)
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter$login$1.invoke(LoginPresenter.kt:58)
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter$login$1.invoke(LoginPresenter.kt:17)

Also i found:

Exception in thread "main" java.lang.NullPointerException
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter.getUserData(LoginPresenter.kt:81)
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter.onLoginSuccess(LoginPresenter.kt:69)
at com.unikrn.esports.umode.ui.welcome.login.LoginPresenter.access$onLoginSuccess(LoginPresenter.kt:17)

Solution

  • I found the solution not better i think, if you have sme better, I`ll like to see it)

    I just add second given after first

    @Test
    fun login() {
    
    given(loginUseCase.run(LoginUseCase.LoginRequest(USER_LOGIN, USER_PASSWORD,"en")))
        .willReturn(Single.just(LoginResponse(
            false,
        "ok",
        "id",
        "name",
        "userId")))
    
    given(getUserDataUseCase.run())
            .willReturn(
                Single.just(
                    UserData(
                        1,
                        false,
                        "",
                        "",
                        isLoggedIn = true,
                        canBet = true,
                        isDisabled = false,
                        canBetSkill = true,
                        isVerifiedOrPending = false
                    )
                )
            )
    
    presenter.login(USER_LOGIN, USER_PASSWORD)
    
    verify(deviceSharedPreferences,atLeastOnce()).setSessionId("id")
    

    }