2013-03-21 12 views
16

Ich bin neu in Mockito, ich habe versucht, in diese Ausnahme zu suchen, aber ich habe keine konkrete Antwort gefunden. Es passiert in meinem Code, wenn ich zwei Mocks zusammen benutze, was bedeutet, dass ich durch den Konstruktor einen Mock, einen weiteren Mock gebe. Wie so:Mockito UnfinishedStubbingException

... 
OperationNode child = getNode(Operation.ADD); 
child.insertNode(getConstantNode(getIntegerValue(2)); 
... 

private ConstantNode getConstantNode(NumericalValue value){ 
    ConstantNode node = Mockito.mock(ConstantNode.class); 
    Mockito.when(node.evaluate()).thenReturn(value); 
    Mockito.when(node.toString()).thenReturn(value.toString()); 
    return node; 
} 

private IntegerValue getIntegerValue(int number) { 
    IntegerValue integerValue = Mockito.mock(IntegerValue.class); 
    Mockito.when(integerValue.getValue()).thenReturn(number); 
    Mockito.when(integerValue.toString()).thenReturn(Integer.toString(number)); 
    return integerValue; 
} 

In einem der Foren las ich über keinen Mock durch einen Konstruktor eines anderen Mock senden, da Mockito könnte mit den mock Anrufe verwirrt, so habe ich versucht, die folgenden:

NumericalValue value = getIntegerValue(2); 
child.insertNode(getConstantNode(value)); 

Aber ohne Erfolg. Ich stelle sicher, dass nur die Methoden toString() und getValue() aufgerufen werden, da dies die einzigen Methoden der Klasse sind. Ich verstehe nicht, was los ist.

Ich habe versucht, auch separat die Mocks verwenden, um zu sehen, ob ich etwas falsch gemacht haben:

child.insertNode(new ConstantNode(getIntegerValue(2))); 

, die perfekt funktioniert.

child.insertNode(getConstantNode(new IntegerValue(2))); 

Das funktioniert auch gut.

+1

bekanntes Problem 'https: //code.google.com/p/mockito/issues/detail? Id = 53' –

+2

Anklickbarer Link: https://code.google.com/p/mockito/issues/detail? id = 53 –

Antwort

22

Von dem, was ich las auf "Ausgabe 53" von Mockito (https://code.google.com/p/mockito/issues/detail?id=53) tun kann, war mein Code ein Problem aufgrund der Validation Framework in Mockito beteiligt erlebt. Genau der folgende Code verursachte die Ausnahme an sich.

private ConstantNode getConstantNode(NumericalValue value){ 
    ConstantNode node = Mockito.mock(ConstantNode.class); 
    Mockito.when(node.evaluate()).thenReturn(value); 
    Mockito.when(node.toString()).thenReturn(value.toString()); 
    return node; 
} 

Wenn Sie von meinem Code erinnern, ist der Parameterwert AUCH A MOCK, so dass, wenn value.toString() auf dem thenReturn() genannt wird, glaube ich (und jemand bitte korrigieren Sie mich, wenn ich falsch bin), dass die Validation Framework ist ausgelöst und stellt sicher, dass jedes "wenn" hat seine thenReturn() genannt/validiert/etc. Wenn das passiert, wird Mockito.when(node.toString()).thenReturn(value.toString()nicht validiert, weil es nicht von der valute.toString() zurückgekehrt ist, die die ganze Kette "validiere alles" gestartet hat.

Wie ich es fest:

private ConstantNode getConstantNode(NumericalValue value){ 
    ConstantNode node = Mockito.mock(ConstantNode.class); 
    Mockito.when(node.evaluate()).thenReturn(value); 

    String numberToString = value.toString(); 

    Mockito.when(node.toString()).thenReturn(numberToString); 
    return node; 
} 

Auf diese Weise es kann validiert werden. Ich finde das ein kompletter Code-Geruch, weil ich buchstäblich einen Kommentar hinterlassen muss, der erklärt, warum ich eine scheinbar nutzlose Zwischenvariable im Code verwende.

Danke für die Hilfe.

+0

Danke! Endlich beginne ich dieses seltsame Problem zu verstehen. –

+0

Ich bin froh, dass ich helfen konnte! – Chayemor

0

Ich denke, das ist ein Problem mit der Bestellung der Aufrufe und Mockito Framework Validierung. Versuchen Sie dies und sehen, ob es hilft:

... 
OperationNode child = getNode(Operation.ADD); 
IntegerValue value = getIntegerValue(2); 
ConstantNode node = Mockito.mock(ConstantNode.class); 
Mockito.when(node.evaluate()).thenReturn(value); 
Mockito.when(node.toString()).thenReturn(value.toString()); 
child.insertNode(node); 

... 

private IntegerValue getIntegerValue(int number) { 
    IntegerValue integerValue = Mockito.mock(IntegerValue.class); 
    Mockito.when(integerValue.getValue()).thenReturn(number); 
    Mockito.when(integerValue.toString()).thenReturn(Integer.toString(number)); 
    return integerValue; 
} 

Quelle: https://code.google.com/p/mockito/issues/detail?id=53

+0

Ist das nicht das Gleiche, nur ohne eine Methode auf dem Weg? ... Entweder ich habe es versucht, nutzlos. – Chayemor

2

denke ich, das Problem mit der Linie ist

Mockito.when(node.toString()).thenReturn(value.toString()); in Verfahren getConstantNode

Versuchen Sie, die Linie zu entfernen und überprüfen, ob es funktioniert . sein kann Sie so etwas wie

int num = 2; 
child.insertNode(getConstantNode(getIntegerValue(num), num); 
... 

private ConstantNode getConstantNode(NumericalValue value){ 
    ConstantNode node = Mockito.mock(ConstantNode.class); 
    Mockito.when(node.evaluate()).thenReturn(value); 
    Mockito.when(node.toString()).thenReturn(Integer.toString(number)); 
    return node; 
} 

private IntegerValue getIntegerValue(int number) { 
    IntegerValue integerValue = Mockito.mock(IntegerValue.class); 
    Mockito.when(integerValue.getValue()).thenReturn(number); 
    return integerValue; 
} 
+0

Woher kommt die "Nummer"? – AHungerArtist

+0

Es löste das Ausnahmeproblem, aber ich verstehe immer noch nicht die Dynamik, warum es passiert. Ich habe den Link gelesen, der im ersten Kommentar platziert wurde, aber ich verstehe es immer noch nicht. – Chayemor

4

Es gibt einige gute Korrekturen, die bereits in dieser Frage gepostet wurden, aber für jeden, der immer noch Schwierigkeiten hat, es zu verstehen, denke an die Reihenfolge, in der Java all diese Methoden aufruft. Nach dem Java Language Specification, Java evaluates every parameter of a method left-to-right before calling the method:

  1. integerValue.getValue(), die Mockito
  2. when aufzeichnet, wo Mockito den letzten Anruf (auf integer.getValue) und beginnt mit der Einrichtung stubbing
  3. value.toString, die eine verspottete Anruf kommt, dass Mockito zeichnet
  4. thenReturn auf dem Glutabstreifer

Mockito beschwert sich genau, weil der Aufruf des Mocks, Schritt 3, passiert nach Schritt 2() aber vor Schritt 4 (thenReturn), verursacht die Validierung Framework zu beschweren über die Stubbing. Freude, deine Antwort bewegt den mühsamen Schritt 3 vor Schritt 1, was in Ordnung ist; Sajan entfernt es vollständig von der Aussage, was auch gut ist.