Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify Method called throws Null Pointer exception. #271

Closed
nawinkhatiwada opened this issue Aug 4, 2018 · 12 comments
Closed

Verify Method called throws Null Pointer exception. #271

nawinkhatiwada opened this issue Aug 4, 2018 · 12 comments

Comments

@nawinkhatiwada
Copy link

Method to Test from presenter

`
override

fun syncLocalOrders(syncOrders: SyncOrders) {
    if (syncOrders.orders.isNotEmpty()) {
        view.showProgressDialog("Syncing Successful Call's")
        repository.syncLocalOrder(syncOrders)
                .subscribe({
                    var syncMessage = if (it.failure.count() > 0) {
                        "Call Synced Failed"
                    } else {
                        "Call synced successfully."
                    }
                    view.hideProgressDialog()
                    getUnsuccessfulCallData(false, syncMessage) //Null Pointer Exception
                    updateDatabase(it)
                }, {
                    view.hideProgressDialog() // and enters here too after null pointer exception
                    view.showAlertDialog("Error", ErrorMessageFactory.createMessage(it))
                })
    } else {
        getUnsuccessfulCallData(true, "")
    }
}`

`
@VisibleForTesting

internal fun getUnsuccessfulCallData(showDialog: Boolean, syncMessage: String) {
    repository.getUnsuccessfulCallData()
            .subscribe({
                if (it.noOrders.isNotEmpty()) {
                    syncUnsuccessfulCallData(it, syncMessage)
                } else {
                    view.hideProgressDialog()
                    if (showDialog) {
                        view.showAlertDialog("", "no orders to sync")
                    } else {
                        if (syncMessage.isNotEmpty())
                            view.showSnackBar(syncMessage)
                    }

                }

            }, {
                it.printStackTrace()
            })
}

`

`
@test

fun syncLocalOrders_OrderNotEmptySuccessTest() {
    val order = Order(
            outletId = 1,
            startDate = "Start Date",
            endDate = "End Date",
            syncLat = 9090.09009,
            syncLng = 909009.990,
            offRoute = 1,
            notes = "notes",
            remarks = "Remarks",
            totalPromotionDiscount = 9090.998,
            totalAmount = 90.90,
            inventory = null,
            promotionOrders = null
    )
    val listOfOrder = listOf(order, order)

    val syncOrder = SyncOrders(listOfOrder)
    val success = listOf(1, 2, 3, 4)
    val failure = listOf<Int>()
    val orderResponse = OrderResponse(success, failure)
    whenever(repository.syncLocalOrder(syncOrder)).thenReturn(Observable.just(orderResponse))

    presenter.syncLocalOrders(syncOrder)
    verify(view).showProgressDialog(anyString())
    verify(view).hideProgressDialog()
    verify(presenter, times(1)).getUnsuccessfulCallData(eq(false),  "Call synced successfully.")
    verify(presenter, times(1)).updateDatabase(orderResponse)

}`

The main issue here is whenever I try to run the test syncLocalOrders_OrderNotEmptySuccessTest(), the code enters to both subscribe and throwable of fun syncLocalOrders(syncOrders: SyncOrders) (this was got by keeping breakpoints.) And what I knew was the code enters to throwable after getting Null Pointer Exception on getUnsuccessfulCallData(false, syncMessage) and the test fails Saying something like view.hideProgressDialog() wanted 1 time but was 2 times. Can anybody tell me what am I doing wrong?

@nawinkhatiwada nawinkhatiwada changed the title Verify Method called or not throws Null Pointer exception. Verify Method called throws Null Pointer exception. Aug 4, 2018
@bohsen
Copy link

bohsen commented Aug 10, 2018

verify(view).hideProgressDialog()implicitly means the same as verify(view, times(1)).hideProgressDialog().

Your code probably calls hideProgressDialog() twice. Maybe try setting a breakpoint and run the test in debugmode.

@nawinkhatiwada
Copy link
Author

When I run the test in debug mode, I get Null Pointer Exception whenever I try to verify getUnsuccessfulCallData(false, syncMessage) is called or not. But why do I get Null Pointer Exception here ?

@bohsen
Copy link

bohsen commented Aug 13, 2018

Have you tried

verify(presenter, times(1)).getUnsuccessfulCallData(eq(false), eq("Call synced successfully."))

or

verify(presenter).getUnsuccessfulCallData(eq(false), eq("Call synced successfully."))

@nawinkhatiwada
Copy link
Author

Yes I did, But getting same error Null Pointer Exception. Do I need to mock the request that I have done inside getUnsuccessfulCallData(showDialog: Boolean, syncMessage: String ) to verify the method?

@bohsen
Copy link

bohsen commented Aug 13, 2018

Then try

verify(presenter).getUnsuccessfulCallData(eq(false), anyString())

There's a limitation in Mockito-kotlin verifying non-null parameters - it's mentioned in the wiki.

@nawinkhatiwada
Copy link
Author

Not Working :'( :'(

@bohsen
Copy link

bohsen commented Aug 13, 2018

Change getUnsuccessfulCallData(showDialog: Boolean, syncMessage: String) to open instead of internal or enable mock-maker-inline (if you haven't already).

@nawinkhatiwada
Copy link
Author

Ok, Lemme give a try.

@nhaarman
Copy link
Collaborator

What is the current status? Also, always include the full stack trace if there is one, and try to remove as much noise as possible from the code that has no relation to the issue.

@nawinkhatiwada
Copy link
Author

I tried all the suggestions that you have mentioned but couldn't solve the issue.
I have added the stacktrace below:

` org.mockito.exceptions.verification.TooManyActualInvocations:
view.hideProgressDialog();
Wanted 1 time:
-> at com.rosia.today.TodayPagePresenterTest.syncLocalOrders_OrderNotEmptySuccessTest(TodayPagePresenterTest.kt:67)
But was 2 times. Undesired invocation:
-> at com.rosia.today.TodayPagePresenter$syncLocalOrders$2.accept(TodayPagePresenter.kt:75)

at com.rosia.today.TodayPagePresenterTest.syncLocalOrders_OrderNotEmptySuccessTest(TodayPagePresenterTest.kt:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

`

As I have already mentioned on previous conversation, after debugging the code, I came to know that verifying call of function
getUnsuccessfulCallData(false, syncMessage) throws Null Pointer Exception which is inside subscribe of fun syncLocalOrders(syncOrders: SyncOrders)

@nawinkhatiwada
Copy link
Author

nawinkhatiwada commented Sep 11, 2018

@bohsen @nhaarman

I am running through the same problem again. Verify method called throws Null Pointer Exception
Please review the below code:

    class NotesDialogPagePresenterTest {

    @Mock
    private lateinit var repository: OrderSummaryRepository
    @Mock
    private lateinit var view: NotesDialogPageContract.View
    @Mock
    private lateinit var context: Context

    private lateinit var presenter:NotesDialogPagePresenter
    private val notes = "abcd"
    private val remarks = "xyz"



    @Before
    fun setup(){
        MockitoAnnotations.initMocks(this)
        whenever(view.getContext()).thenReturn(context)

    }

    @Test
    fun onCompleteCallClicked_successTest(){
        whenever(repository.updateOrderAfterCompleteCall(notes,remarks)).thenReturn(Completable.complete())
        this.presenter = NotesDialogPagePresenter(view,repository)

        val spyPresenter = Mockito.spy(presenter)
        spyPresenter.onCompleteCallClicked(notes,remarks)

        verify(view, times(1)).showOnCompleteCallSuccess()
        verify(spyPresenter, times(1)).updateUser()     // Null Pointer Exception Here
    }
}
    class NotesDialogPagePresenter @Inject constructor(var view: NotesDialogPageContract.View,
                                                   var repository: OrderSummaryRepository)
    : NotesDialogPageContract.Presenter {

    private var disposable: Disposable? = null

    override fun start() {
    }

    override fun onCompleteCallClicked(notes: String, remarks: String) {

        disposable = repository.updateOrderAfterCompleteCall(notes, remarks)
                .subscribe({
                    view.showOnCompleteCallSuccess()
                    updateUser()
                }, {
                    view.showError(it)
                })
    }

    @VisibleForTesting
    internal fun updateUser() {
        disposable = repository.updateUser(-1)
                .subscribe({
                    //NO-OP
                }, {
                    //NO-OP
                })
    }

    override fun stop() {
        disposable?.dispose()
    }
}

updateUser() method verification throws Null Pointer Exception

Logcat


java.lang.NullPointerException
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter.updateUser$app_pgDebug(NotesDialogPagePresenter.kt:30)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter$onCompleteCallClicked$1.run(NotesDialogPagePresenter.kt:22)
	at io.reactivex.internal.observers.CallbackCompletableObserver.onComplete(CallbackCompletableObserver.java:54)
	at io.reactivex.internal.disposables.EmptyDisposable.complete(EmptyDisposable.java:68)
	at io.reactivex.internal.operators.completable.CompletableEmpty.subscribeActual(CompletableEmpty.java:27)
	at io.reactivex.Completable.subscribe(Completable.java:1794)
	at io.reactivex.Completable.subscribe(Completable.java:1860)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter.onCompleteCallClicked(NotesDialogPagePresenter.kt:20)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter.onCompleteCallClicked(NotesDialogPagePresenter.kt:19)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenterTest.onCompleteCallClicked_successTest(NotesDialogPagePresenterTest.kt:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Exception in thread "main" java.lang.NullPointerException
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter.updateUser$app_pgDebug(NotesDialogPagePresenter.kt:30)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter$onCompleteCallClicked$1.run(NotesDialogPagePresenter.kt:22)
	at io.reactivex.internal.observers.CallbackCompletableObserver.onComplete(CallbackCompletableObserver.java:54)
	at io.reactivex.internal.disposables.EmptyDisposable.complete(EmptyDisposable.java:68)
	at io.reactivex.internal.operators.completable.CompletableEmpty.subscribeActual(CompletableEmpty.java:27)
	at io.reactivex.Completable.subscribe(Completable.java:1794)
	at io.reactivex.Completable.subscribe(Completable.java:1860)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter.onCompleteCallClicked(NotesDialogPagePresenter.kt:20)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenter.onCompleteCallClicked(NotesDialogPagePresenter.kt:19)
	at com.rosia.bcp.ordersummary.notes.NotesDialogPagePresenterTest.onCompleteCallClicked_successTest(NotesDialogPagePresenterTest.kt:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)

FYI: I am using following versions of Gradle dependencies:

    testImplementation 'org.mockito:mockito-core:2.19.0'
    testImplementation 'com.squareup.retrofit2:retrofit-mock:2.3.0'
    testImplementation 'org.mockito:mockito-inline:2.8.9'
    testImplementation 'com.nhaarman:mockito-kotlin-kt1.1:1.6.0'
    testImplementation 'junit:junit:4.12'

@nhaarman
Copy link
Collaborator

Your repository instance is mocked and thus will return null for all unstubbed method calls. Since you didn't stub the updateUser function it returned null and the NPE is thrown.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants