Ana Koridze
estoy tratando de probar ViewModel
para asegurarse de que livedata se actualice correctamente. Sin embargo al usar ArgumentMatchers.any()
falla con IllegalStateException
dicho:
ArgumentMatchers.any(mViewModel.CountSubscriber::class.java) no debe ser nulo
@Test
fun emitValueIfCountIs7() {
doAnswer { invocation: InvocationOnMock ->
val subscriber: mViewModel.CountSubscriber = invocation.getArgument(0)
subscriber.onNext(7)
null
}.`when`(countUseCase).execute(
ArgumentMatchers.any(mViewModel.CountSubscriber::class.java),
ArgumentMatchers.any(Parameters::class.java)
)
// When
mViewModel.getCount()
// Verify
assert(mViewModel.countResponse.value != null)
}
Estoy usando Kotlin y tengo las siguientes dependencias:
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-inline:2.23.4"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
Aquí están mis importaciones:
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.nhaarman.mockitokotlin2.doAnswer
import io.reactivex.Observable
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.invocation.InvocationOnMock
Lo extraño es que solía funcionar antes, y no sé qué ha pasado que podría afectar esto.
Nabzi
Lograr que los comparadores trabajen con Kotlin puede ser un problema. Si tiene un método escrito en kotlin que no acepta un parámetro anulable, entonces no podemos hacer coincidir con él usando Mockito.any(). Esto se debe a que puede devolver void y esto no se puede asignar a un parámetro que no admite valores NULL.
Si el método que se empareja está escrito en Java, entonces creo que funcionará ya que todos los objetos de Java son implícitamente anulables.
Una posible solución sería utilizar una biblioteca como Mockito-kotlin
Pero usted mismo puede resolver este problema fácilmente con unas pocas líneas de código.
Si necesita escribir alguno (tipo: Clase)
private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
O
Puede usar este comparador en lugar de Matchers.any() :
object MockitoHelper {
fun <T> anyObject(): T {
Mockito.any<T>()
return uninitialized()
}
@Suppress("UNCHECKED_CAST")
fun <T> uninitialized(): T = null as T
}
y use MockitoHelper.anyObject()
en vez de any()
en tus pruebas de kotlin.
Puedes encontrar más información en este post: Usando Mockito con Kotlin
Hay una discusión sobre posibles soluciones en esta publicación: ¿Es posible usar Mockito en Kotlin?
-
Muchas gracias por esta explicación y estas respuestas. La primera clase escrita fn funcionó perfectamente para mí.
– orfeo
31 oct 2021 a las 19:12
Haomin
La solución correcta se menciona en la sección de comentarios de la pregunta de @Ana Koridze. Sí, si está usando Koltin + mockitoKotlin. Asegúrese de que está utilizando la siguiente importación:
1 – Usando el Mockito-kotlin:
import org.mockito.kotlin.any
de Mockito-kotlin en lugar de
import org.mockito.Mockito.any
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
2 – O si está utilizando una versión anterior de mockito kotlin original creada por nhaarman antes de la interacción
import com.nhaarman.mockitokotlin2.any
de Mockito-kotlin de nhaaram en lugar de import org.mockito.Mockito.any
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin2_version"
Por cierto, si está utilizando Android Studio o IntelliJ IDEA. la any()
de la biblioteca de mockitokotlin debe ser italic
por estilo/esquema de color predeterminado.
Observe la any()
al final de la línea. Esto es de maqueta
Y aquí está el any()
de maqueta
Gracias @Sattar por la edición recomendada.
-
lo unico que me funciono. Gracias @haomin
– Nouman Ch.
10 de marzo de 2021 a las 18:54
-
¡Tuve el mismo problema y luego leí su respuesta y verifiqué mis importaciones y ahora funciona! ¡Gracias!
– Maroung
6 de octubre de 2021 a las 10:18
-
Salvaste mi día. ¡Gracias!
– Arkadi
8 de noviembre de 2021 a las 12:41
usar Mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
esto usará cualquiera que funcione para kotlin ya que esta es una librería contenedora para Mockito pero para kotlin
Mockito-kotlin ha agregado soporte para argumentos anulables con anyOrNull()
`when`(myMock.doesThis(any(), anyOrNull())).thenReturn(someObject)
bastami82
Esto es lo que funcionó para mí,
- o reemplazó todos los genéricos
any()
s , con un anyTYPE() específico, es deciranyInt()
,anyList()
etc. de core liborg.mockito:mockito-core
y soluciona el problema (de anulabilidad), parece que las definiciones específicas con tipo pueden manejar nulo. esta opción no requiere que importe ninguna biblioteca adicional
o
- si realmente necesita usar el tipo genérico
any()
agregue esta extensión lib oficial de Mckito https://github.com/mockito/mockito-kotlin y asegúrese de usar elany()
de esta biblioteca (asegurándose de que sus importaciones tengan esto en ella)import org.mockito.kotlin.any
)
Sugiero comenzar a usar MockK lib https://github.com/mockk/mockk en lugar de Mockito ya que es un Mock
biblioteca para K
otlin = MockK)
sin embargo, si le da pereza cambiar ahora mismo o tal vez esté lidiando con pruebas heredadas (como en mi caso :), esto también debería solucionar su problema.
Gad Wissberg
Para mí, todas las soluciones anteriores no fueron suficientes, además de eso, tuve que marcar el método llamado como un método ‘abierto’. De acuerdo a esto:
https://github.com/mockito/mockito-kotlin/wiki/Parameter-specified-as-non-null-is-null
El método es definitivo y Mockito no pudo burlarse de él, así que tuve que agregar ‘abierto’.
¿Puede publicar sus importaciones? IIRC esto puede suceder cuando se usa el comparador que no es kotlin con código kotlin.
– fweigl
7 dic 2019 a las 21:11
Actualicé la pregunta con importaciones.
– Ana Koridze
7 dic 2019 a las 21:53
ArgumentMatchers.any(Class type) siempre devuelve nulo sin importar el objeto que estoy tratando de hacer coincidir
– Ana Koridze
8 de diciembre de 2019 a las 10:43
Tenías razón, reemplacé las dependencias de org.mockito con las de com.nhaarman.mockitokotlin2 y ¡ahora funciona!
– Ana Koridze
8 de diciembre de 2019 a las 11:01