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

Unable to test presenter ? #297

Open
devendroid opened this issue Jan 16, 2020 · 9 comments
Open

Unable to test presenter ? #297

devendroid opened this issue Jan 16, 2020 · 9 comments

Comments

@devendroid
Copy link

devendroid commented Jan 16, 2020

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?

@rcfgnu
Copy link

rcfgnu commented Jan 16, 2020

You have to provide a mock to the actual call at the use case method inside the presenter.

@devendroid
Copy link
Author

I have followed the same as this test class UserListPresenterTest

@devendroid
Copy link
Author

Hi @rcfgnu , Have you found anything wrong/missing in my code from UserListPresenterTest class?

@epetrenko
Copy link

@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.

@devendroid
Copy link
Author

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))
    }
}

@epetrenko
Copy link

@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.

@devendroid
Copy link
Author

@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))
......

@epetrenko
Copy link

@devendroid try to do the following instead of defining generic type:

execute(any(DisposableObserver.class), any(Void.class))

@devendroid
Copy link
Author

devendroid commented Feb 3, 2020

@epetrenko It's not allowing in kotlin, forcing to convert like this Void::class.java .

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

No branches or pull requests

3 participants