2015-05-18 15 views
25

Il problema che sto affrontando è che Matchers.anyObject() restituisce null. Quando viene utilizzato per il metodo di simulazione che accetta solo tipi non annullibili, genera un'eccezione "Non dovrebbe essere nulla" da lanciare.È possibile utilizzare Mockito in Kotlin?

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

metodo deriso:

public open fun login(userCredentials: UserCredentials): Response 
+1

C'è una discussione su un sito della comunità kotlin su come evitare questo problema, verificarlo: https://devnet.jetbrains.com/thread/443551 – SimY4

+0

Grazie. Sembra che devnet.jetbrains.com non sia molto ben indicizzato da google. – atok

risposta

31

ci sono due possibili soluzioni:

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

L'altra soluzione è

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

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

Ecco some more discussion su questo argomento, in cui il worka il primo è suggerito.

+5

Credo che SO ti chieda gentilmente di replicare il contenuto del link anche nella tua risposta, in modo che se il link dovesse mai andare a vuoto, questa risposta è comunque utile. –

+0

Purtroppo, nella 1.0.0-beta-4584 questa soluzione non sembra funzionare più: 'kotlin.TypeCastException: null non può essere lanciato su un tipo X non nullo'. – nhaarman

+0

@nhaarman funziona perfettamente per me, potresti indicarmi il caso esatto? –

7

Io uso verify molto per assicurarsi che anche i parametri passati a una funzione siano corretti.

Per eseguire questa operazione ed evitare comunque l'NPE, è possibile utilizzare l'operatore elvis di Kotlin. per esempio: verify(mock).func(same(my_obj) ?: my_obj)

questo modo, Mockito è soddisfatto perché in realtà verifica la variabile e Kotlin è soddisfatto perché si passa un oggetto non nullo.

Un'altra cosa che mi sono imbattuto era la biblioteca Mockito-Kotlin che risolve proprio questo problema https://github.com/nhaarman/mockito-kotlin

2

È possibile utilizzare le seguenti funzioni di supporto per utilizzare Mockito di qualsiasi(), eq() e la cattura() 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() 

Vedi MockitoKotlinHelpers.kt dal repository Android architettura Blueprints da Google.

2

Per coloro che hanno bisogno digitato any(type: Class<T>)

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

Questo potrebbe funzionare ed il controllo di tipo avviene anche!