2015-06-05 7 views
5

EDIT: Ich habe erstellt schließlich eine issue auf Mockito Github-Projekt.Mockito returnsFirstArg() funktioniert nicht mit generischen ersten arg

Ich versuche, die typisierte Methode getNameElement der Schnittstelle RoomGeneralService zu verspotten die erste arg zurück, mit Mockito AdditionalAnswers.returnsFirstArg Funktionalität:

Schnittstelle zu verspotten:

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

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

Mein Test (beachten Sie die Importe)

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()); 
     //... 
    } 
} 

Auch habe ich mit anderen Kombinationen ausprobiert, aber bisher ohne Erfolg:

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

Fehler empfangen:

Der Grund für diesen Fehler können sein: 1. Der wollte Argument Position ist falsch. 2. Die Antwort wird auf die falsche Interaktion verwendet.

Position des gesuchten Arguments 0 ist und das mögliche Argument Indizes für diese Methode ist: [0]

Abhilfe Objekt

Ich weiß, dass ich meine eigene Antwort erstellen, und in der Tat, es funktioniert gut, wenn statt Verwendung returnFirstArg() ich etwas wie folgt aus:

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

Aber ich würde returnFirstArg() wie im Rest meiner Tests verwenden (Tests sauberer aussehen), sowie das Spotten funktioniert gut, wenn die Methode getNameElement ein String statt T arg erhalten würde.

Danke für die Hilfe.

Antwort

0

entschied ich mich schließlich ein Problem (#1071) auf Mockito Github-Projekt zu öffnen und es hat mich in der Version 2.8.29 (Siehe den offiziellen changelog) Dank des Mockito Team zu lösen es so schnell behoben!

@ChristianSchwarz Zitiert, hier ist ein Problem Erklärung:

Mockito prüft, ob das Argument Typ mit dem Rückgabetyp kompatibel ist ein Missbrauch ot die API so bald wie möglich sichtbar zu machen. In diesem Fall wird das Argument-Typ Object aus dem generischen Typ T aufgrund Art Löschen abgeleitet. Da Objekt kein Untertyp von String ist, wirft Mockito die Ausnahme, die Sie sehen.

Lösung: Das Problem kann durch Ableiten des Argumenttyps der tatsächlichen Argument-Instanz behoben werden. Falls der Argumenttyp ein Primitiv ist oder der Arg ist null, muss Mockito zurückfallen und den Typ verwenden, der von der Methodensignatur bereitgestellt wird.

1

Es scheint, Mockito ist nicht schlau genug, um daraus abzuleiten, dass der Parametertyp im parametrierten Subinterface an String gebunden ist.

Sie können die Methode in der

Subschnittstelle außer Kraft setzen
interface RoomGeneralService extends PrimaryKeyElement<String> { 
    @Override 
    public String getNameElement(String primaryKey); 
} 

Mockito nicht erraten müssen. Es wird deutlich String als der Parametertyp der Stubbed-Methode angezeigt.

+0

Zunächst einmal, vielen Dank für die Beantwortung. Leider ist das Überschreiben von Methoden keine Option für das Projekt. Wenn Mockito das nicht kann, gehe ich lieber mit der Problemumgehung fort. – troig

+0

@troig Sie kontrollieren nicht den Quellcode dieser Schnittstellen? –

+0

Nein, das ist das Problem. Danke für deine Annäherung. – troig

Verwandte Themen