Unable to test presenter ?
Hi, I have implemented the same architecture in kotlin but when I'm mocking a UseCase class, it's not initializing, my presenter test class is below:
private var presenter:SetAddressPresenter? = null
@Mock
private var mockContext: Context? = null
@Mock
private var controller: Controller? = null
@Mock
private lateinit var setAddressUseCase: SetAddressUseCase
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
presenter = SetAddressPresenter(setAddressUseCase)
presenter?.setAddressController(controller)
}
@Test
fun testUserListPresenterInitialize() {
given(controller?.context()).willReturn(mockContext)
presenter?.loadPreviousAddresses()
verify(controller)?.hideRetry()
verify(controller)?.showLoading()
verify(setAddressUseCase)?.execute(
any(SetAddressPresenter.SetAddressObserver::class.java),
any(Void::class.java) )
}
Getting the NullPointerException on ...domain.interactor.UseCase.execute(UseCase.kt:53)
my UseCase Class is:
..........
init {
compositeDisposable = CompositeDisposable()
this.threadExecutor = threadExecutor
this.postExecutionThread = postExecutionThread
}
fun execute(observer: DisposableObserver<T>, params: Any?) {
val observable = this.buildUseCaseObservable(params)
.subscribeOn(Schedulers.from(threadExecutor)) // Line no 53
.observeOn(postExecutionThread.getScheduler())
addDisposable(observable.subscribeWith(observer))
}
..........
Could you please help or advice on this?
You have to provide a mock to the actual call at the use case method inside the presenter.
I have followed the same as this test class UserListPresenterTest
Hi @rcfgnu , Have you found anything wrong/missing in my code from UserListPresenterTest class?
@devendroid as I understood, NPE appeared because buildUseCaseObservable(params) method returned null.
Can you try the following to match types of the parameters in execute() method declaration:
verify(setAddressUseCase)?.execute(
any(DisposableObserver.class),
any(Params.class))
Also try to remove lateinit from setAddressUseCase, cause it is marked as lateinit, but I don't see where it is initialized. And make other mocks non nullable.
Thanks, @epetrenko, to give the hint for NPE, I have resolved this, but now on verify execute method I'm getting this Exception:
E/TestRunner: org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type CountSurveyUseCase and is not a mock!
.........
Now my test class is:
class SetAddressPresenterTest {
private lateinit var countSurveyUseCase: CountSurveyUseCase
private lateinit var presenter:SetAddressPresenter
@Mock private var mockContext: Context? = null
@Mock private var controller: Controller? = null
@Mock private lateinit var surveyRepository: SurveyRepository
@Before
fun setUp() {
given(controller?.context()).willReturn(mockContext)
given { surveyRepository.countSurvey() }.willReturn( Observable.empty() )
countSurveyUseCase = CountSurveyUseCase(surveyRepository)
presenter = SetAddressPresenter(countSurveyUseCase)
presenter.setAddressController(controller!!)
}
@Test
fun testSetAddressPresenter() {
presenter?.checkOrdersInDraft()
verify(surveyRepository).countSurvey()
verifyNoMoreInteractions(surveyRepository)
verify(countSurveyUseCase)?.execute(
any(DisposableObserver::class.java) as DisposableObserver<Int>,
any(Any::class.java))
}
}
@devendroid it happened because countSurveyUseCase is defined as lateinit var and initialized manually instead of using @Mock annotation. verify() method accepts only @Mock annotated parameters.
@epetrenko I have mocked the countSurveyUseCase using @Mock annotation, but now I stuck on verify execute, Matchers.any( - ) not allowing generic types, showing a message "Only classes are allowed on the left-hand side of a class literal"
.......
verify(countSurveyUseCase)?.execute(
any(DisposableObserver<Int>::class.java), // Showing syntax error on here
any(Void::class.java))
......
@devendroid try to do the following instead of defining generic type:
execute(any(DisposableObserver.class), any(Void.class))
@epetrenko It's not allowing in kotlin, forcing to convert like this Void::class.java .