2017-05-22 1 views
1

Ich versuche, eine Methode, deren Signatur zu verspotten ist:Mockito ändern Argument Wert von nicht void-Methode

public A doSomething(B b, String str){} 

Ich versuchte str Wert unter Verwendung doAnswer zu aktualisieren. Diese Methode gibt jedoch das Objekt A mit Werten zurück, die bedingt gesetzt sind. Ich bin nicht in der Lage, einen Weg zu finden, um den spezifischen str-Wert festzulegen, der an diese Methode übergeben werden soll. Kann mir bitte jemand sagen, wie das erreicht werden kann? Ich kann powermock nicht in meinem Projekt verwenden.

+0

verstehe ich richtig, dass Sie Anrufe an Ihre verspottet wollen Methode, um ihr Argument zu ändern? Das ist unmöglich, da Strings unveränderlich sind. Da keine Implementierung dieser Schnittstelle möglicherweise so etwas tun kann, warum sollte Ihr Mock-Objekt das tun? – ohlec

+0

Was möchten Sie testen? Was meinst du mit "mit Werten, die bedingt gesetzt sind?" – pvpkiran

+0

@pvpkiran, ich meine, ich kann Objekt A einfach von der Methode doAnswer zurückgeben. Ich möchte, dass es von der Methode zurückgegeben wird. –

Antwort

1

Für einmalige Mocks, können Sie InvocationOnMock.getArguments verwenden Sie den Wert von str zu erhalten:

doAnswer(new Answer<Foo>() { 
    @Override public Foo answer(InvocationOnMock invocation) { 
    A a = mock(A.class); 
    when(a.someMethod()).thenReturn((String) (invocation.getArguments()[0])); 
    return a; 
    } 
}).when(yourObject).doSomething(any(B.class), anyString()); 

// or with Java 8: 
doAnswer(invocation => { 
    A a = mock(A.class); 
    when(a.someMethod()).thenReturn((String) (invocation.getArguments()[0])); 
    return a; 
}).when(yourObject).doSomething(any(), anyString()); 

... aber solange das Verfahren mockable ist (sichtbar und nicht-final), können Sie auch schreiben Sie Ihre neue Methode inline als anonyme innere Unterklasse (oder eine statische Unterklasse definiert an anderer Stelle), die die gleiche Sache, ohne so viel Gießen und Mockito Syntax erreichen kann:

YourObject yourObject = new YourObject() { 
    @Override public A someMethod(B b, String str) { 
    A a = mock(A.class); 
    when(a.someMethod()).thenReturn(str); 
    return a; 
    } 
}; 
+0

Ich bin nicht interessiert, was zurückgegeben wird. Ich dachte daran, Str als einen Stub zur Verfügung zu stellen. Aber es sieht so aus, als ob es nicht möglich ist für nicht void Methoden. Ich habe meinen Code überarbeitet. Ich habe eine neue Methode für den Codeabschnitt erstellt, in dem ich diese Zeichenfolge gelesen und dann den Wert zurückgegeben habe. –

+0

Beachten Sie, dass Sie den Begriff "Mock", wie er üblicherweise verwendet wird, nicht verwenden ("Ersetzung der Implementierung von"), der normalerweise für Abhängigkeiten gilt, nicht für das zu testende System (SUT). Wenn "doSomething" ein Teil Ihres SUT ist, dann ist es eine schlechte Idee, es zu verspotten oder zu verpacken, und Sie sollten es direkt in Ihrer Strategie mit einem beliebigen "str" ​​aufrufen. Wenn es in einer Abhängigkeit ist, dann können Sie diese Abhängigkeit vortäuschen, 'str' ignorieren und zurückgeben, was Sie wollen. Wenn das Problem in statischen Methodenabhängigkeiten besteht, gibt es viele Möglichkeiten, einen _testing seam_ ohne Powermock einzuführen. –

+0

yeah Ich habe dieses Problem wegen der statischen Methode. Ich kann powermock nicht verwenden, da es keine genehmigte Bibliothek in meinem Kunden-Repository ist. –