2015-06-05 8 views
5

EDIT: Ho finalmente creato un issue sul progetto di Mockito github.Mockito returnsFirstArg() non funziona con generico primo arg

sto cercando di prendere in giro il metodo digitato getNameElement di interfaccia RoomGeneralService per tornare al primo arg, utilizzando Mockito AdditionalAnswers.returnsFirstArg funzionalità:

interfaccia per deridere:

interface PrimaryKeyElement<T> { 
    public String getNameElement(T primaryKey); 
} 

interface RoomGeneralService extends PrimaryKeyElement<String> { 
    // ... 
} 

Il mio test (notare le importazioni)

import static org.mockito.AdditionalAnswers.returnsFirstArg; 
import static org.mockito.Matchers.any; 
import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.when; 

@RunWith(PowerMockRunner.class) 
public class SampleTest { 

    @Mock 
    RoomGeneralService roomGeneralService; 

    @Test 
    public void testFoo() throws Exception { 
     when(roomGeneralService.getNameElement(anyString())).thenAnswer(returnsFirstArg()); 
     //... 
    } 
} 

Inoltre ho provato con altre combinazioni, ma senza successo finora:

when(roomGeneralService.getNameElement(Matchers.<String>any())).thenAnswer(returnsFirstArg()); 
doAnswer(returnsFirstArg()).when(roomGeneralService.getNameElement(anyString())); 
doReturn(returnsFirstArg()).when(roomGeneralService.getNameElement(anyString())); 

errore ricevuto:

La ragione di questo errore può essere: 1. L'argomento ha voluto la posizione è errata 2. La risposta viene utilizzata nell'interazione errata.

Posizione dell'argomento desiderato è 0 e le possibili indici argomento per questo metodo sono: [0] oggetto

Soluzione:

So che posso creare la mia risposta, e infatti funziona bene se invece di utilizzare returnFirstArg() faccio qualcosa del genere:

when(roomGeneralService.getNameElement(anyString())).thenAnswer(new Answer<String>() { 
    @Override 
    public String answer(InvocationOnMock invocation) throws Throwable { 
     return (String) invocation.getArguments()[0]; 
    } 
}); 

Ma vorrei usare returnFirstArg() come nel resto dei miei test (i test sembrano più puliti), così come il mocking sta funzionando bene se il metodo getNameElement avrebbe ricevuto un String invece un T arg.

Grazie per l'aiuto.

risposta

0

ho finalmente deciso di aprire un problema (#1071) sul progetto github Mockito ed è stato risolto nella versione 2.8.29 (vedi la documentazione ufficiale changelog) Grazie al team Mockito risolverlo così in fretta!

Citando @ChristianSchwarz, ecco una spiegazione problema:

controlli Mockito se il tipo di argomento è compatibile con il tipo di ritorno fare un uso improprio ot l'API appena possibile visibile. In questo caso l'argomento -oggetto viene dedotto dal tipo generico T, a causa tipo cancellazione. Dal momento che oggetto non è un sottotipo di stringa Mockito getta l'eccezione che si vede.

Soluzione: il problema può essere risolto inferendo il tipo di argomento dell'istanza-argomento effettiva . Nel caso l'argomento tipo è un primitivo o arg è nullo Mockito deve ripiego Utilizzando questo tipo è fornito da firma del metodo.

1

Sembra che Mockito non sia abbastanza intelligente da dedurre che il tipo di parametro sarà associato a String nella subinterfaccia parametrizzata.

è possibile ignorare il metodo nel subinterface

interface RoomGeneralService extends PrimaryKeyElement<String> { 
    @Override 
    public String getNameElement(String primaryKey); 
} 

Mockito non dovrà indovinare. Vedrà chiaramente String come il tipo di parametro del metodo stubbed.

+0

Prima di tutto, grazie per la risposta. Sfortunatamente il metodo di sovrascrittura non è un'opzione per il progetto. Se Mockito non può farlo, preferisco continuare con la soluzione alternativa. – troig

+0

@troig Non controllare il codice sorgente di queste interfacce? –

+0

No, questo è il problema. Grazie per il tuo approccio comunque. – troig

Problemi correlati