95

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
atok
  • 5,880
  • 3
  • 33
  • 62
  • 2
    There's a discussion on a kotlin community site on how to avoid this problem, check it out: https://devnet.jetbrains.com/thread/443551 – Alex May 18 '15 at 14:16
  • 1
    Thank you. Seems like devnet.jetbrains.com is not very well indexed by google. – atok May 18 '15 at 14:30

6 Answers6

87

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.

Marcin Koziński
  • 10,835
  • 3
  • 47
  • 61
Sergey Mashkov
  • 4,630
  • 1
  • 27
  • 24
53

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!

Shamm
  • 1,004
  • 7
  • 9
40

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.

makovkastar
  • 5,000
  • 2
  • 30
  • 50
  • 2
    Looks like the URL is moved to: https://github.com/googlesamples/android-architecture/blob/todo-mvp-kotlin/todoapp/app/src/test/java/com/example/android/architecture/blueprints/todoapp/MockitoKotlinHelpers.kt – Surekha Mar 16 '18 at 14:21
  • Great thanks! Works with latest version of Mockito as well (v3.3.3) and Kotlin (v1.3.72) – Fatmajk Jul 01 '20 at 07:50
11

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

maxandron
  • 1,650
  • 2
  • 12
  • 16
2

it just need to return a nonnull result when you use Mockito.any();

Mockito.any() ?: 0
Mockito.any() ?: HashMap<Int,Int>()
Mockito.any() ?: {}

...

max li
  • 21
  • 1
1

To extend on the answer provided by @makovkastar, you can provide a nullable or non-nullable Matcher like this:

/**
 * Matcher that returns null
 */
private inline fun <reified T> any(): T = Mockito.any<T>()

/**
 * Matcher never returns null
 */
private inline fun <reified T> any(type: Class<T>): T = Mockito.any(type)
VIN
  • 6,385
  • 7
  • 38
  • 77