Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Mockito in Kotlin?

The problem I'm facing is that Matchers.anyObject() returns null. When used to mock method that only accepts non-nullable types it causes a "Should not be null" exception to be thrown.

`when`(mockedBackend.login(anyObject())).thenAnswer { invocationOnMock -> someResponse }

Mocked method:

public open fun login(userCredentials: UserCredentials): Response
like image 941
atok Avatar asked May 18 '15 13:05

atok


People also ask

Can we use Mockito with Kotlin?

Mockito-Kotlin extensions are fairly easy and fun to use - they introduce DSL for mocks and stubs, increasing readability and helping avoid long complex mock configurations in test suite.

Can we mock interface using Mockito?

The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called.

What is the use of Mockito Any ()?

Mockito allows us to create mock objects and stub the behavior for our test cases. We usually mock the behavior using when() and thenReturn() on the mock object.


4 Answers

There are two possible workarounds:

private fun <T> anyObject(): T {
    Mockito.anyObject<T>()
    return uninitialized()
}

private fun <T> uninitialized(): T = null as T

@Test
fun myTest() {
    `when`(mockedBackend).login(anyObject())).thenAnswer { ... }
}

The other workaround is

private fun <T> anyObject(): T {
    return Mockito.anyObject<T>()
}

@Test
fun myTest() {
    `when`(mockedBackend).login(anyObject())).thenAnswer { ... }
}

Here is some more discussion on this topic, where the workaround is first suggested.

like image 155
Sergey Mashkov Avatar answered Oct 26 '22 08:10

Sergey Mashkov


For those who need typed any(type: Class<T>)

    private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)

This would work and the type check also happens!

like image 28
Shamm Avatar answered Oct 26 '22 09:10

Shamm


You can use the following helper functions to use Mockito's any(), eq() and capture() matchers in Kotlin:

/**
 * Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when
 * null is returned.
 *
 * Generic T is nullable because implicitly bounded by Any?.
 */
fun <T> eq(obj: T): T = Mockito.eq<T>(obj)

/**
 * Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when
 * null is returned.
 */
fun <T> any(): T = Mockito.any<T>()

/**
 * Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException
 * when null is returned.
 */
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()

See MockitoKotlinHelpers.kt from the Android Architecture Blueprints repository by Google.

like image 20
makovkastar Avatar answered Oct 26 '22 10:10

makovkastar


I use verify a lot to make sure the parameters passed to a function are also correct.

To do this, and still avoid the NPE you can use kotlin's elvis operator. for example: verify(mock).func(same(my_obj) ?: my_obj)

This way, mockito is satisfied because it actually verifies the variable, and kotlin is satisfied because we pass a non null object.

Another thing I stumbled upon was the mockito-kotlin library which solves exactly this issue https://github.com/nhaarman/mockito-kotlin

like image 25
maxandron Avatar answered Oct 26 '22 09:10

maxandron