Reputation: 478
I am getting Null Pointer Exception
whenever I try to verify method is called or not.
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)
this.presenter = NotesDialogPagePresenter(view, repository)
}
@Test
fun onCompleteCallClicked_successTest() {
whenever(repository.updateOrderAfterCompleteCall(notes, remarks)).thenReturn(Completable.complete())
val spyPresenter = Mockito.spy(presenter)
spyPresenter.onCompleteCallClicked(notes, remarks)
verify(view, times(1)).showOnCompleteCallSuccess()
verify(spyPresenter, times(1)).updateUser()//Null Pointer Exception Here
}
}
Presenter Class
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()
}
}
These two methods need to be verified and updateUser() throws Null Pointer Exception
view.showOnCompleteCallSuccess()
updateUser()
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 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'
Upvotes: 1
Views: 5679
Reputation: 2157
I had a similar issue and it turned out that methods that are to be mocked should be marked as open
Here is an example of code that will work:
class ToBeMocked {
open fun myName() = "ToBeMocked"
}
class MyClass(val it: ToBeMocked) {
fun myName() = it.myName()
}
class MyClassTest {
val myMock: ToBeMocked = mock()
val sut = MyClass(myMock)
@Test
fun test() {
whenever(myMock.myName()).thenReturn("Test")
assertThat(sut.myName()).equalsTo("Test")
}
}
Upvotes: 0
Reputation: 11
If you don't want to mock the output for the updateUser()
you may implement a presenter interface class and verify if the presenterinterface function is invoked.
Step 1: Add a presenter interface class
interface INotesDialogPagePresenter {
fun updateUser()
}
Step 2: Implement the interface class to your presenter
class NotesDialogPagePresenter @Inject constructor(var view:NotesDialogPageContract.View,var repository: OrderSummaryRepository)
: NotesDialogPageContract.Presenter,INotesDialogPagePresenter {
private var disposable: Disposable? = null
var implNotesDialogPagePresenter :INotesDialogPagePresenter = this
override fun start() {
}
override fun onCompleteCallClicked(notes: String, remarks: String) {
disposable = repository.updateOrderAfterCompleteCall(notes, remarks)
.subscribe({
view.showOnCompleteCallSuccess()
implNotesDialogPagePresenter.updateUser()
}, {
view.showError(it)
})
}
override fun updateUser() {
disposable = repository.updateUser(-1)
.subscribe({
//NO-OP
}, {
//NO-OP
})
}
override fun stop() {
disposable?.dispose()
}
Step 3: Update your test class (using mockito-kotlin)
class NotesDialogPagePresenterTest {
val view:NotesDialogPageContract.View= mock()
val repository:OrderSummaryRepository= mock()
val context:Context= mock()
val implNotesDialogPagePresenter :INotesDialogPagePresenter = mock()
private lateinit var presenter: NotesDialogPagePresenter
private val notes = "abcd"
private val remarks = "xyz"
@Before
fun setup() {
whenever(view.getContext()).thenReturn(context)
this.presenter = NotesDialogPagePresenter(view, repository)
presenter.implNotesDialogPagePresenter = implNotesDialogPagePresenter
}
@Test
fun onCompleteCallClicked_successTest() {
whenever(repository.updateOrderAfterCompleteCall(notes, remarks)).thenReturn(Completable.complete())
val spyPresenter = Mockito.spy(presenter)
spyPresenter.onCompleteCallClicked(notes, remarks)
verify(view, times(1)).showOnCompleteCallSuccess()
verify(implNotesDialogPagePresenter , times(1)).updateUser()
}
This way, you don't actually running the updateUser(), instead you'll just verify if the mocked interface object's fun being invoked. This prevents null pointer and incerease your test coverage.
Upvotes: 1
Reputation: 5063
Since you're mocking OrderSummaryRepository
you'll have to mock out every method call that the consuming class i.e. in this case the NotesDialogPagePresenter
calls on. So as Chris pointed out, you'll have to add a mock for updateUser()
repository.updateUser(anyInt()) doReturn any()
Upvotes: 0
Reputation: 2362
You're not mocking the updateUser call.
You need to add something like the following into your test setup, depending on what updateUser is expected to return.
whenever(repository.updateUser(-1)).thenReturn(Completable.complete())
Upvotes: 2