Mockito nicht werfen nicht korrigieren Ausnahme bei Verwendung doThrow auf einen Spion
Ich bin mit PowerMock (Mockito), zu verhöhnen, eine subcall zu einer anderen Methode in der gleichen Klasse. Genauer gesagt ich habe so etwas wie dieses:
public class myClass{
public void MyMethod1(){
//do something
try{
myMethod2();
} catch (MyExceptionType e) {
//do something
throw e;
}
}
public int MyMethod2() throws MyExceptionType {...}
}
Nun in meine unit-tests, die ich in der Lage bin, zu verspotten, die Reaktionen der MyMethod2 mit einem Spion, und etwas zu tun, wie doReturn(1).when(myClass).myMethod2()
. Aber etwas seltsames passiert, wenn ich etwas wie das hier tun: doThrow(myExeptionType).when(myClass).myMethod2()
. Wenn ich Anrufe, myClass.myMethod1() bei meinem test, es wirft eine NullPointerException, aber das seltsame bit ist, dass wenn ich einen debugger verwenden, und überprüfen throw e
, e ist die richtige Ausnahme des Typs MyExceptionType.
Hier ist der StackTrace der NullPointerException:
java.lang.NullPointerException
at java.util.Arrays$ArrayList.<init>(Arrays.java:2842)
at java.util.Arrays.asList(Arrays.java:2828)
at org.mockito.internal.exceptions.stacktrace.StackTraceFilter.filter(StackTraceFilter.java:31)
at org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter.filter(ConditionalStackTraceFilter.java:23)
at org.mockito.internal.invocation.realmethod.FilteredCGLIBProxyRealMethod.invoke(FilteredCGLIBProxyRealMethod.java:29)
at org.mockito.internal.invocation.InvocationImpl.callRealMethod(InvocationImpl.java:108)
at org.mockito.internal.stubbing.answers.CallsRealMethods.answer(CallsRealMethods.java:36)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:93)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:51)
at com.amazon.inventory.workflow.common.wrapper.FCContainerServiceWrapper$$EnhancerByMockitoWithCGLIB$$a0f00456.getContainerHierarchyDown(<generated>)
at com.amazon.inventory.workflow.common.wrapper.containerservice.GetContainerHierarchyDownTest.runTest(GetContainerHierarchyDownTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:110)
at org.junit.rules.RunRules.evaluate(RunRules.java:18)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:148)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Hoffentlich meine Frage ist nicht zu verwirrend, vielen Dank!
doThrow(myExeptionType)
, meinst du Sie haben instanziiert eine variable myExeptionType
? Wenn ja, was ist der Wert? Oder meinst du, dass Sie schrieb MyExceptionType.class
? Könntest du bitte GENAU posten den code, der verursacht das problem, so dass wir es reproduzieren können; anstatt nur zu beschreiben? Danke.Ich finde auch deine groß-und Kleinschreibung verwirrend. Sie haben geschrieben beide
myMethod2
und MyMethod2
für die gleiche Methode, die darauf schließen lässt, dass das, was du gepostet hast ist nicht der eigentliche code, die Ihnen das problem. Sie auch verwendet, Kleinbuchstaben für myClass
. Vielleicht ist es nicht relevant, aber der nicht-standard-Verwendung von groß-und Kleinschreibung macht deine Beispiel schwieriger zu Folgen.Auch dein StackTrace deutet darauf hin, dass Sie eine
ExpectedException
Regel. Sie haben nicht gezeigt, uns diese zu. Können, so tun Sie dies bitte? Es könnte Auswirkungen auf das, was hier passiert.Sorry, meine Frage war verwirrend. Ich habe festgestellt, dass das Problem liegt in der Tatsache, dass mockito ist versucht, meine verspottet exception - stackTrace, der null ist, und dann versucht zu filtern, dass die Ergebnisse in einer NPE. Ich gebe das als Antwort, in der Hoffnung, dass es vielleicht jemand anderes helfen.
InformationsquelleAutor Nepoxx | 2013-11-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Kommentare und die anschließende Antwort haben, offenbart sich das problem. Sie versuchen, zu verspotten, Ihr exception-Objekt. Mockito wurde nicht entwickelt, um in der Lage sein, dies zu tun. Der Grund dafür ist, dass Ausnahmen werden im Allgemeinen als value-Objekte. Sie transportieren Informationen - eine Botschaft, einen stack-trace, manchmal ein Verweis auf eine zweite Ausnahme; aber als Allgemeine Regel gilt, dass Sie nicht wirklich jede Funktion.
Zwecke der Spott, jede Klasse ist ein Objekt, das hat keine eigene Funktionalität, das heißt, keiner von seinen Methoden nichts tun, außer dort, wo explizit umgesetzt werden innerhalb der test. Aber eine Ausnahme passt schon, Kriterium, also es ist nichts damit gewonnen, wenn lustig. Die Beratung bei http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html ist guter Rat in der Tat.
So, Sie haben ein paar Optionen, die beide Ihr problem zu lösen sehr schön.
(1) Erstellen Sie eine echte Ausnahme und verwenden Sie, die in Ihrem test. Je nachdem, was Konstruktoren
MyException
hat, könnte dies wie folgt Aussehen.(2) Lassen Mockito erzeugen des exception-Objekts für Sie, nur durch Angabe seiner Klasse
doThrow
nennen.InformationsquelleAutor Dawood ibn Kareem
Habe ich herausgefunden, dass das Problem befand sich in der Tatsache, dass mockito versucht heraus zu filtern, die stack-trace der exception geworfen, um die zu entfernen "EnhancedByMockito" strings angehängt verspottet Klasse Namen. Also im Grunde, was ich hier Tue:
Natürlich, in diesem Beispiel
mockedException.getStackTrace()
würde null zurückgeben, das würde dann erstellen Sie einen null-Zeiger-Ausnahme aus, wenn Mockito versucht zu filtern, die stack-trace.Ich hoffe, dies klärt meine Frage und könnte für jemanden nützlich.
Um das Problem zu lösen, habe ich einfach verspottet einen stack-trace für meine Ausnahme etwa so:
Ich denke, das ist eher eine "philosophische" Frage der Herangehensweise, da am Ende beide arbeiten. Ich möchte, unit-Tests, die Methode, und die Methode nur, und lustig IRGENDWELCHE Abhängigkeiten. Vielleicht bin ich zu streng, wie ich Vorgehen unit-tests?
Gut, wenn es eine Verwendung für Sie, ich könnte in der Lage sein, Sie zu überreden, die Mockito-team zum hinzufügen eines
doMockAndThrow
- Methode, oder etwas ähnliches, kümmert sich um die Verspottung der stack-trace zu. So, dass Sie schreiben würdendoMockAndThrow(ExceptionType.class).when(someMock).someMethod()
Aber mir scheint es, dass Ausnahme-Klassen sind "Wert" - Klassen, - Sie speichern einige Daten, aber Sie nicht haben in der Regel die Funktionalität Ihrer eigenen, und deshalb verspotten Sie gewinnt nichts, und geht gegen einen der zentralen Grundsätze der Spott.Jetzt haben Sie klargestellt, dass Ihr Problem wurde "verspottet ich den exception-Typ", ich denke, ich werde nach meiner eigenen Antwort auf diese Frage, so dass alle zukünftigen Menschen, die nicht finden, diese Frage, glaube nicht, dass das deine Antwort ist der einzige Ansatz.
Vereinbart. Werde ich auch mal upvote 🙂 Danke David!
InformationsquelleAutor Nepoxx
Denken Sie daran, zu behaupten die Ausnahme in der test-Methode. Wie durch die Verwendung der JUnit-annotation:
InformationsquelleAutor javaPlease42