2013-04-09 5 views
22

Mockito scheint eine UnfinishedVerificationException zu werfen, wenn ich denke, dass ich alles richtig gemacht habe. Hier ist mein Teil-Testfall:Mockito gibt UnfinishedVerificationException, wenn es OK scheint

HttpServletRequest req = mock(HttpServletRequest.class); 
when(req.getHeader("Authorization")).thenReturn("foo"); 

HttpServletResponse res = mock(HttpServletResponse.class); 

classUnderTest.doMethod(req, res); // Use the mock 

verify(res, never()); 
verify(req).setAttribute(anyString(), anyObject()); 

Und hier ist der Teil-Klasse und Methode:

class ClassUnderTest extends AnotherClass { 
    @Override 
    public String doMethod(ServletRequest req, ServletRequest res) { 
     // etc. 
     return "someString"; 
    } 
} 

Das Ignorieren der Tatsache, dass Sie sollten nie Mock Schnittstellen, die Sie nicht besitzen, warum Mockito mich geben die folgende Botschaft?

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here: 
-> at (redacted) 

Example of correct verification: 
    verify(mock).doSomething() 

Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods. 
Those methods *cannot* be stubbed/verified. 

at [test method name and class redacted] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:160) 
... etc 
+0

Wie sieht die Klasse des 'classUnderTest' aus? Wie lautet die Signatur der Methode? Es funktioniert gut mit öffentlichen nicht-finalen Klassen/Methoden. –

+0

Ich habe die Frage mit dem ClassUnderTest aktualisiert – Jonathan

+6

Ist die Zeile, auf die in der Nachricht verwiesen wird (die Sie redigiert haben) die gleiche wie die Zeile, in der die Ausnahme tatsächlich ausgelöst wird? Wenn Sie eine nicht abgeschlossene Überprüfung haben, meldet Mockito dies normalerweise erst im nächsten Mockito-Verfahren. Es kann gut sein, dass Ihr Problem in der Testmethode VOR diesem Fall liegt. Deshalb meldet Mockito die Zeilennummer, wo der Fehler SEPARATIV von der Stack-Trace selbst auftritt. –

Antwort

38

Ich bin gerade auf mich gestoßen und es hat mich sehr verwirrt.

Wie oben erwähnt David Mockito Fehler in der nächsten Mockito Methodenaufruf, die möglicherweise nicht in der gleichen Testmethode. Während die Ausnahmebedingungsnachricht einen Verweis auf die tatsächliche Stelle enthält, an der der Fehler aufgetreten ist, finde ich, dass falsche Tests nicht erfolgreich für den Testprozess waren. Und je einfacher die Tests, desto wahrscheinlicher ist ein Fehler im nächsten Test! Hier

ist eine einfache Lösung, die Fehler wird sichergestellt, in der richtigen Testmethode erscheinen:

@After 
public void validate() { 
    validateMockitoUsage(); 
} 

Von der Mockito Dokumentation here:

Mockito wirft Ausnahmen, wenn Sie es missbrauchen, so dass Sie wissen, wenn Ihre Tests korrekt geschrieben sind. Das Problem ist, dass Mockito die Validierung bei der nächsten Verwendung des Frameworks (z. B. das nächste Mal, wenn Sie verifizieren, Stub, Aufruf Mock usw.). Aber obwohl die Ausnahme im nächsten Test geworfen werden kann, enthält die Ausnahmebedingungsnachricht einen navigierbaren Stapel Trace-Element mit der Position des Fehlers. Daher können Sie klicken und finden Sie den Ort, wo Mockito missbraucht wurde.

Manchmal möchten Sie möglicherweise die Framework-Verwendung explizit überprüfen. Zum Beispiel wollte einer der Benutzer validateMockitoUsage() in seiner @After-Methode so setzen, dass er sofort weiß, wenn er Mockito missbrauchte. Ohne es hätte er darüber nicht früher gewusst, als er das nächste Mal das Rahmenwerk verwendete. Ein weiterer Vorteil von validateMockitoUsage() in @After ist, dass jUnit Runner immer in der Testmethode mit Fehler fehlschlägt, während normale 'nächste Zeit' Validierung die nächste Test Methode fehlschlagen kann. Aber auch wenn JUnit den nächsten Test als rot melden sollte, machen Sie sich keine Sorgen darüber und klicken Sie einfach auf das navigierbare Stack-Trace-Element in der Ausnahmebedingungsnachricht , um sofort den Ort zu finden, an dem Sie mockito missbraucht haben.

Zum Beispiel, wenn unsere Methode, um diese Signatur hat:

+0

Siehe MockitoRule-Klasse hier http://StackOverflow.com/Questions/40793464/Parameterized-testing-with-Mockito-by-using-Junit-Rule – tkruse

19

Dies könnte auch, wenn Sie verify ein Verfahren, das mit any() primitiven Argumenten erwartet versuchen verursacht werden

method(long l, String s); 

Und Sie versuchen, überprüfen Sie es so, es wird mit der oben genannten Nachricht fehlschlagen:

Ch ange es anyLong() und es wird funktionieren:

verify(service).method(anyLong(), anyString()); 
+0

Warum nicht ** anyString() ** übergeben? –

+1

@IgorGanapolsky Danke, zu AnyString() geändert –

+0

Sie sind mein persönlicher Held. Vielen Dank. – Robert

0

Ich hatte ähnliche Ausnahme mit Klasse MyRepository

org.mockito.exceptions.misusing.UnfinishedVerificationException: Fehlende Methodenaufruf für überprüfen (mock) hier: -> bei MyRepository $$ FastClassBySpringCGLIB $$ de8d8358.invoke()

Beispiel für eine korrekte Prüfung:

verify(mock).doSomething() 

Das Problem wurde behoben, als ich eine Schnittstelle für MyRepository und eine Scheinschnittstelle, aber keine Implementierung erstellte. Es scheint, dass spring einige CGLIB-Proxies erstellt und zur UnfinishedVerificationException-Ausnahme führt.

1

Für mich stellte sich heraus, dass das Problem eine fehlende Bean-Deklaration im Testkontext XML war. Es war für eine benutzerdefinierte Aspektklasse, die von einer anderen Klasse verwendet wird, deren Instanz ein Parameter für den Konstruktor der Klasse ist, der der Parameter für den fehlgeschlagenen Aufruf von verify() ist. Also habe ich die Bean-Deklaration zum Kontext-XML hinzugefügt und es hat danach gut funktioniert.

Verwandte Themen