Подтвердить что ты не робот

Можно ли использовать Mockito в Котлине?

Проблема, с которой я сталкиваюсь, заключается в том, что Matchers.anyObject() возвращает null. Когда используется для издевательства метода, который принимает только типы, не допускающие null, он вызывает исключение "Не должно быть null".

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

Выделенный метод:

public open fun login(userCredentials: UserCredentials): Response
4b9b3361

Ответ 1

Возможны два способа обхода:

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 { ... }
}

Другим обходным решением является

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

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

Вот еще несколько обсуждений по этой теме, где сначала предлагается обходное решение.

Ответ 2

Я использую verify много, чтобы убедиться, что параметры, переданные функции, также верны.

Чтобы сделать это, и все еще избегать NPE, вы можете использовать оператор kotlin elvis. например: verify(mock).func(same(my_obj) ?: my_obj)

Таким образом, mockito удовлетворен, потому что он фактически проверяет переменную, а kotlin выполняется, потому что мы передаем ненулевой объект.

Еще одна вещь, на которую я наткнулся, была библиотека mockito-kotlin, которая решает именно эту проблему https://github.com/nhaarman/mockito-kotlin

Ответ 3

Вы можете использовать следующие вспомогательные функции для использования Mockito any(), eq() и capture() в 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()

См. MockitoKotlinHelpers.kt из хранилища Google Архитектуры Android Google.

Ответ 4

Для тех, кому нужно набрать any(type: Class<T>)

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

Это будет работать, и проверка типа также произойдет!