Daniel Gomez Rico
Daniel Gomez Rico

Reputation: 15946

Extend Mockito verify for Kotlin not working (in a "kotlin way")

I want to extend verify to allow checking multiple commands over the same mocked object but it is not working, it compiles but on run it dont run each command over the same.

Just want to avoid writing more things like:

Mockito.verify(mockedView).initViews()
Mockito.verify(mockedView).setImage(user.photoUrl)

and write more like:

Mockito.verify(mockedView){
    initViews()
    setImage(user.photoUrl)
}

First try:

@Test
fun onCreate_loadLoginInfo() {
    val user = MockUser.user()

    presenter.onCreate(mockedView, user)

    Mockito.myVerify(mockedView) {
        initViews()
        setImage(user.photoUrl)
        setName(user.name)
        setEmail(user.email)
    }
}

class Mockito {
    companion object
}

fun <T> Mockito.Companion.myVerify(obj: T, func: T.() -> Unit) {
    org.mockito.Mockito.verify(obj).func()
}

Second try:

@Test
fun onCreate_loadLoginInfo() {
    val user = MockUser.user()

    presenter.onCreate(mockedView, user)

    Mockito.myVerify(mockedView) {
        it.initViews()
        it.setImage(user.photoUrl)
        it.setName(user.name)
        it.setEmail(user.email)
    }
}

class Mockito {
    companion object
}

fun <T> Mockito.Companion.myVerify(obj: T, func: (T) -> Unit) {
    val mock = org.mockito.Mockito.verify(obj)
    func(mock)
}

But those are not working, all the tests pass even if I dont call the methods in the presenter, How can I do this?

Upvotes: 1

Views: 1053

Answers (3)

Andrey Paslavsky
Andrey Paslavsky

Reputation: 160

I had the same problems and wrote Facade around Mockito. My library allow to verify few calls around one mock object:

val list = mock(MutableList::class)

list.add("String 1")
list.add("String 2")
list.size()

verify(list) {
    times(2).add(anyString())
    times(1).size()
}

Please look to the readme, maybe it can help you

Upvotes: 3

Denys P.
Denys P.

Reputation: 266

Correct me if I'm wrong. You want to avoid multiple verify() calls in your test.

@Test fun onCreate_loadLoginInfo() {
    // ...

    verify(mockedView).initViews()
    verify(mockedView).setImage(user.photoUrl)
    verify(mockedView).setName(user.name)
    verify(mockedView).setEmail(user.email)
}

I modified your second approach little bit:

@Test fun onCreate_loadLoginInfo() {
    // ...

    verifyAll(mockedView) {
        it().initViews()
        it().setImage(user.photoUrl)
        it().setName(user.name)
        it().setEmail(user.email)
    }
}

fun <T> verifyAll(mock: T, func: (() -> T) -> Unit) {
    func { Mockito.verify(mock) }
}

As you can see now we are passing functional argument to func() and need to use it appropriately (use it as function, not as object).

Upvotes: 2

Michael
Michael

Reputation: 54715

You should do it like that. verify must be called before each mock method invocation.

Upvotes: 0

Related Questions