mockito / mockito-kotlin

Using Mockito with Kotlin
MIT License
3.11k stars 201 forks source link

Can not compare 2 closure parameters #356

Open ekizy opened 5 years ago

ekizy commented 5 years ago

Hi, I have function which has 3 parameters and 2 of these parameters are functions. However when i try to verify a function i get this error.

Argument(s) are different! Wanted:
topHeadlinesRepository.getTopHeadlines(
    TopHeadlinesRequestModel(page=1, pageSize=21, language=en, apiKey=f2430a145094467981aa6dc965fbe7f3),
    fun com.ekiz.googlenewschallenge.domain.TopHeadlinesDataSourceTest.handleSuccess(com.ekiz.googlenewschallenge.data.uimodels.ArticleContainerModel): kotlin.Unit,
    fun com.ekiz.googlenewschallenge.domain.TopHeadlinesDataSourceTest.handleFailure(com.ekiz.googlenewschallenge.util.ErrorException): kotlin.Unit
);
-> at com.ekiz.googlenewschallenge.data.repository.TopHeadlinesRepository.getTopHeadlines(TopHeadlinesRepository.kt:23)
Actual invocation has different arguments:
topHeadlinesRepository.getTopHeadlines(
    TopHeadlinesRequestModel(page=1, pageSize=21, language=en, apiKey=f2430a145094467981aa6dc965fbe7f3),
    (com.ekiz.googlenewschallenge.data.uimodels.ArticleContainerModel) -> kotlin.Unit,
    (com.ekiz.googlenewschallenge.util.ErrorException) -> kotlin.Unit
);
-> 

Here is my function's declaration

fun getTopHeadlines(
    requestModel: TopHeadlinesRequestModel,
    success: (articleContainer: ArticleContainerModel) -> Unit,
    failure: (failure: ErrorException) -> Unit
)

And here is my test function

@Test fun testLoadInitial_success() { whenever(topHeadlinesRepository.getTopHeadlines(requestModel, ::handleSuccess, ::handleFailure)).then { handleSuccess(articleContainerModel) }

    topHeadlinesDataSource.loadInitial(
        PageKeyedDataSource.LoadInitialParams(
            requestedLoadSize,
            placeHoldersEnabled
        ), object :
            PageKeyedDataSource.LoadInitialCallback<Long, ArticleModel>() {

            override fun onResult(
                data: MutableList<ArticleModel>,
                position: Int,
                totalCount: Int,
                previousPageKey: Long?,
                nextPageKey: Long?
            ) = handleSuccess(articleContainerModel)

            override fun onResult(data: MutableList<ArticleModel>, previousPageKey: Long?, nextPageKey: Long?) =
                handleSuccess(articleContainerModel)

        })

    verify(topHeadlinesRepository, times(1)).getTopHeadlines(requestModel, ::handleSuccess, ::handleFailure)
}
bohsen commented 5 years ago

You're trying to verify that getTopHeadlines(...) is passed two function references, but the implementation of getTopHeadlines expects two lambda. AFAIK lambdas and function references are two different things. Have you considered using a Matcher in your verification instead?

Like this: verify(topHeadlinesRepository, times(1)).getTopHeadlines(any(), any(), any())

Fun fact: Function references are actually an example of reflection. This is why the object returned by this type of operation also contains information about the referred function. You can actually do the following with them:

fun isOdd(i: Int) = i % 2 == 1 

val annotations = ::isOdd.annotations 
val parameters = ::isOdd.parameters 
println(annotations.size) // Prints: 0 
println(parameters.size) // Prints: 1