vendredi 29 janvier 2021

Android mockito argument needs to be mock exception

I am trying to test my function with JUnit + Mockito. My function is using Amadeus API to fetch flight offers with given specification.

amadeus.shopping.flightOffers.get(...).handleResponse(
    onSuccess = { response ->
        when (response.isEmpty()) {
            true -> requestStatus.value = Status.EMPTY
            else -> requestStatus.value = Status.SUCCESS
        }
        view?.onSearchFlightSuccess(response)
    },
    onError = { exception, errors ->
        requestStatus.value = Status.FAILED
        view?.onSearchFlightError(exception)
    }
 )

handleResponse function is my extension over Amadeus's ApiResult

fun <T> ApiResult<T>.handleResponse(onSuccess: (T) -> Unit, onError: (Exception?, List<ApiResult.Error.Issue>) -> Unit) {
    when (this) {
        is ApiResult.Success -> onSuccess(data)
        is ApiResult.Error -> onError(exception, errors)
    }
}

So I am not very experienced in testing, but I found many articles on the internet how to do it, but somehow it doesn't work.

@Test
@ExperimentalCoroutinesApi
fun onSearchFlightsButtonClick() = runBlockingTest {
    given(amadeus.shopping).willReturn(mock(Shopping::class.java))
    given(amadeus.shopping.flightOffers).willReturn(mock(FlightOffers::class.java))

    given(amadeus.shopping.flightOffers.get(...))
    .willReturn(mock(ApiResult::class.java) as ApiResult<List<FlightOfferSearch>>)


    `when`(mock(ApiResult::class.java).handleResponse(mock(CallbackSuccess::class.java)::invoke,
        mock(CallbackError::class.java)::invoke)
    ).then { answer -> (answer.arguments[0] as (List<FlightOfferSearch>) -> Unit).invoke(emptyList()) }


    presenter.onSearchFlightsButtonClick()

    Mockito.verify(view).onSearchFlightSuccess(emptyList())
}


interface CallbackSuccess {
    operator fun invoke(value: Any?)
}

interface CallbackError {
    operator fun invoke(exception: Exception?, issues: List<ApiResult.Error.Issue>)
}

I pass interfaces to my extension function because Mockito.any() didn't work and threw up exception: any() can not be null. Can someone point out what is wrong here?

Above code throws:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

Aucun commentaire:

Enregistrer un commentaire