Guten tag, also ich teste grad meine Klasse...und in der Klasse wird eine exception gefangen und eine neue weiter geworfen!
ich weiß nicht wie ich das testen soll, WIe exceptions eigentlich zu testen sind, weiß ich!
doch das Funktioniert nicht oder welche von beiden muss ich überhaupt prüfen???
meine zu testende Klasse:
Java:
publicclassFunctionimplementsIFunction{privatefinalScriptEngine engine;publicFunction(ScriptEngine engine){this.engine = engine;}/**
* Gibt für den übergebenen x Wert ,den errechneten y-Wert zurück.
*
* @param x
* übergebene xKoordinate
* @return yKoordinate
*/@Overridepublicdoublef(double x){Object y;try{
y = engine.eval("f("+ x +");");}catch(ScriptException e){thrownewIllegalStateException(e.getMessage());}return((Number) y).doubleValue();}}
und der test sieht bis jetzt so aus:
Java:
/**
* Prüft ob eine {@link IllegalStateException} geworfen wird, wenn falsche
* Werte übergeben werden.
*
* @throws Exception
*/@Test(expected =IllegalStateException.class)publicvoidillegalState()throwsException{
function = math.eval("5x");
function.f(1);}
Du musst deinem zu testenden Objekt eine [c]ScriptEngine[/c] (ein Mock) unterschieben, das beim Aufruf von eval() einfach eine ScriptException wirft. Hierfür würde sich ein Mocking-Framework anbieten.
Du musst deinem zu testenden Objekt eine [c]ScriptEngine[/c] (ein Mock) unterschieben, das beim Aufruf von eval() einfach eine ScriptException wirft. Hierfür würde sich ein Mocking-Framework anbieten.
ja also mit mocken ahbe ich es auch schon versucht!
aber da war nciht ein test bei mir grün!
der test zum Beipiel geht:
Java:
/**
* Prüft ob zu der linearen Funktion und dem übergeben x-Wert der richtige y-Wert
* errechnet wird.
*
* @throws Exception
*/@TestpublicvoidlinearFunction()throwsException{
function = math.eval("5*x+1");Object result = function.f(-2.0);Object y =-9.0;assertThat(((Number) result).doubleValue(),is(((Number) y).doubleValue()));}
Du musst deinem zu testenden Objekt eine [c]ScriptEngine[/c] (ein Mock) unterschieben, das beim Aufruf von eval() einfach eine ScriptException wirft. Hierfür würde sich ein Mocking-Framework anbieten.
/**
* Prüft ob eine {@link IllegalStateException} geworfen wird, wenn falsche
* Werte übergeben werden.
*
* @throws Exception
*/@TestpublicvoidillegalState()throwsException{//@formatter:off
context.checking(newExpectations(){{oneOf(engine).eval("sf");will(returnValue(ScriptException.class));}});//@formatter:on
function.f(1);}}
/**
* Prüft ob eine {@link IllegalStateException} geworfen wird, wenn falsche
* Werte übergeben werden.
*
* @throws Exception
*/@Test(expected =IllegalStateException.class)publicvoidillegalState()throwsException{
function =newFunction(engine);//@formatter:off
context.checking(newExpectations(){{
engine.eval("abc");
result=newScriptException("");}});//@formatter:on
function.f(0.0);// assertThat(function.f(0.0), is(result));;}}
;(;(
und ich habe mocking auch bisschen anders gelernt und habe es noch mal so implementiert und da kommt eine andere fehler meldung, was ja noch kurioser ist!!!
ist doch eigentlich das gleiche oder?
Java:
/**
* Prüft ob eine {@link IllegalStateException} geworfen wird, wenn falsche
* Werte übergeben werden.
*
* @throws Exception
*/@Test(expected =IllegalStateException.class)publicvoidillegalState()throwsException{
function =newFunction(engine);//@formatter:off
context.checking(newExpectations(){{oneOf(engine).eval("abc");will(returnValue(newScriptException("")));}});//@formatter:on
function.f(0.0);// assertThat(function.f(0.0), is(result));;}}
fehlermeldung:
java.lang.Exception: Unexpected exception, expected<java.lang.IllegalStateException> but was<java.lang.AssertionError>
@Test(expected =IllegalStateException.class)publicvoidillegalState()throwsException{
function =newFunction(engine);//@formatter:off
context.checking(newExpectations(){{oneOf(engine).eval("f(0.0);");will(returnValue(newScriptException("")));}});//@formatter:onObject result = function.f(0.0);((Number)result).doubleValue();}}
so geht es nciht, da kommt nun eine classCastException
und auserdem will ich ja gucken ob die exception weiter geworfen wird,deswegen muss ich ja ein Fehler einbauen oder nicht?????????:L
Das tust du ja, indem du die ScriptException erzeugst. Allerdings weiß ich nicht, ob das korrekt mit dem will(returnValue(..)) funktioniert, den die Exception muss ja geworfen werden und nicht mit return zurück geliefert. Ich weiß nicht, was für ein Mocker du benutzt, mit JMockit geht es so wie oben beschrieben.
Edit: Ich seh grad, in meinem Beispiel ist ein Fehler. In Zeile 10 muss natürlich ScriptException stehen.
Das tust du ja, indem du die ScriptException erzeugst. Allerdings weiß ich nicht, ob das korrekt mit dem will(returnValue(..)) funktioniert, den die Exception muss ja geworfen werden und nicht mit return zurück geliefert. Ich weiß nicht, was für ein Mocker du benutzt, mit JMockit geht es so wie oben beschrieben.
Edit: Ich seh grad, in meinem Beispiel ist ein Fehler. In Zeile 10 muss natürlich ScriptException stehen.
Ich benutze JMock und ich kenne das nur nach dem schema ...
bei deinem code beispiel hat mich das result so verwirrt!?muss ich damit nicht irgendwas machen?
oder so???
Mit [c]result=...[/c] legt man fest, was die gemockte Methode als ergebnis zurückliefert ([c]returns(...)[/c] gibt's auch, aber das funktioniert etwas anders). Wenn das Objekt, das man result zuweist, ein Throwable ist, wirft die Methode dieses Throwable. Genau das willst du erreichen. Finde heraus, wie das mit JMock funktioniert, und der Test sollte klappen. Das returnValue gibt die Exception wahrscheinlich nur als Ergebnis zurück - was auch die ClassCastException erklären würde.
Mit JMock sieht das irgendwie facked aus... Hier mal EasyMock
Java:
privateScriptEngine engine =createMock(ScriptEngine.class);@Test(expected=IllegalStateException.class))publicvoidscriptExceptionIsForwardedAsIllegalArgumentException(){Function func =newFunction(engine);expect(engine.eval(isA(String.class))).andThrows(newScriptException("tattaa ! exception ist daa!"));replay(engine);// oder replayAll wenn Dein Test EasyMockSupported, verify() und reset() ins tearDown
func.f(0.0);}