mockito-kotlin icon indicating copy to clipboard operation
mockito-kotlin copied to clipboard

Mockito calls the real method, stubbing does not work

Open uburoiubu opened this issue 6 years ago • 4 comments
trafficstars

I have the following test:

private var interceptSelectedRoute = mock<InterceptSelectedRoute>()
@Captor
val interceptSelectedRouteCaptor = argumentCaptor<DisposableObserver<DetailedRoute>>()
@Test
    fun `when selected route is intercepted, we should start persisting it`() {

        doNothing().`when`(interceptSelectedRoute).dispose()

        interactor.start()

        val selectedRoute = NavigatorRouteFactory.makeDetailedRoute()

        verify(interceptSelectedRoute).execute(interceptSelectedRouteCaptor.capture(), eq(null))

        interceptSelectedRouteCaptor.firstValue.onNext(selectedRoute)

        assertEquals(
                expected = NavigatorStateMachine.State.Initialization.PersistingRoute(selectedRoute),
                actual = interactor.stateMachine.state
        )
    }

Inside interactor there is this method invocation:

private fun stopInterceptingSelectedRoute() {
        interceptSelectedRoute.dispose()
   }

interceptSelectedRoute is a child of the following class:

abstract class ObservableUseCase<T, in Params> constructor(
        private val postExecutionThread: PostExecutionThread
) {

    val subscriptions = CompositeDisposable()

    abstract fun buildUseCaseObservable(params: Params? = null): Observable<T>

    open fun execute(observer: DisposableObserver<T>, params: Params? = null) {
        val observable = this.buildUseCaseObservable(params)
                .subscribeOn(Schedulers.io())
                .observeOn(postExecutionThread.scheduler)

        observable.subscribeWith(observer).disposedBy(subscriptions)
    }

    fun dispose() {
        subscriptions.clear()
    }

}

When stopInterceptingSelectedRoute() is invoked, I get NullPointerException because subscriptions == null.

I don't understand why doNothing() does not work here as expected (meaning that the real method is not invoked). Could you help?

uburoiubu avatar Dec 20 '18 16:12 uburoiubu

It is probably because dispose() is not open, so Mockito can not stub final method

SidyakinAV avatar Jan 18 '19 11:01 SidyakinAV

I have the same issue. Host is an enum and initializeHost is a method within that enum.

    Host(int resource) {
        initializeHost(resource);
    }

    @SuppressWarnings("ResourceType")
    public void initializeHost(int resource) {
        ....
    }

I would like doNothing() on initializeHost. But every time I run the test initializeHost runs

private val host = Host.testServer
    
@Test
fun test1() {
    // GIVEN
    testSubject = RequestCookieInterceptor(cookiesManager, host)

    doNothing().whenever(cmxHost.initializeHost(any()))

    // WHEN
    val response = testSubject.intercept(interceptorChain)

    // THEN
    assert(response.request().header(HttpHeaders.COOKIE) == COOKIE)
}

aliillyas avatar Feb 03 '19 17:02 aliillyas

@aliillyas

Host is an enum and initializeHost is a method within that enum.

As far as I know enums can't be mocked. Can I ask why it's an enum? This would be very strange design to me.

bohsen avatar Feb 04 '19 10:02 bohsen

This is an older enum implementation, I think its time to convert it to a class. Thank you for the answer.

aliillyas avatar Feb 04 '19 14:02 aliillyas