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

Can not compare 2 closure parameters

Open ekizy opened this issue 5 years ago • 1 comments

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

ekizy avatar Aug 23 '19 17:08 ekizy

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 

bohsen avatar Aug 24 '19 22:08 bohsen