{"id":21056,"date":"2017-04-25T09:00:02","date_gmt":"2017-04-25T08:00:02","guid":{"rendered":"https:\/\/www.inovex.de\/blog\/?p=3026"},"modified":"2022-12-01T08:42:09","modified_gmt":"2022-12-01T07:42:09","slug":"exception-testing-junit-4","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/","title":{"rendered":"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019]"},"content":{"rendered":"<p>Im Laufe der Zeit hat das Testing Framework JUnit 4 immer raffiniertere Verfahren angeboten, um das Verhalten in Ausnahmef\u00e4llen (Exceptions) zu testen. Um aber auch mit der aktuellen Methode alle relevanten Aspekte abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.<!--more--><\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Der-Unit-Test-an-sich\" >Der Unit-Test an sich<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Das-Verhalten-im-Ausnahmefall-testen\" >Das Verhalten im Ausnahmefall testen<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Der-klassische-Exception-Test-mit-JUnit-4\" >Der klassische Exception Test mit JUnit 4<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Der-Exception-Test-mit-Annotation\" >Der Exception Test mit Annotation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Der-Exception-Test-mit-Rule\" >Der Exception Test mit Rule<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Aspekte-des-Verhaltens-im-Ausnahmefall\" >Aspekte des Verhaltens im Ausnahmefall<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#Functional-Interfaces-to-the-rescue\" >Functional Interfaces to the rescue<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Der-Unit-Test-an-sich\"><\/span>Der Unit-Test an sich<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Ein einzelner Unit-Testfall soll alle relevanten Aspekte des Verhaltens der <code>UnitUnderTest<\/code> bei der Ausf\u00fchrung einer konkreten Funktion pr\u00fcfen und sicherstellen. Dabei ist die Funktion im Kontext ihres Zustandes, des Verhaltens ihrer Kollaborateure und eventueller Eingabedaten zu betrachten. Das zu pr\u00fcfende Verhalten besteht vornehmlich aus einem eventuellen Ergebnis sowie aus der Interaktion mit den Kollaborateuren. Die Struktur eines solchen Tests entspricht g\u00e4ngigerweise dem folgenden Muster.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Standard Unit-Test\">@Test\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ call function\r\n\r\n  Object result = unitUnderTest.executeFunction(input);\r\n\r\n  \/\/ check result and behaviour\r\n\r\n  assertThat(result, is(EXPECTED_RESULT));\r\n\r\n  verifyColaboratorInteractions();\r\n\r\n}\r\n\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Das-Verhalten-im-Ausnahmefall-testen\"><\/span>Das Verhalten im Ausnahmefall testen<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Neben dem produzieren des erw\u00fcnschten Ergebnisses im Normalfall soll eine Funktion h\u00e4ufig auch ein bestimmtes Verhalten im Ausnahmefall zeigen. Ausnahmen treten immer dann auf, wenn der aktuelle Kontext von Zustand und Verhalten der beteiligten Akteure der Unit die Ausf\u00fchrung der aufgerufenen Funktion unm\u00f6glich macht. Das kann eine ung\u00fcltige Eingabe sein oder aber ein unerwartetes Verhalten eines Kolaborateurs. In diesem Fall l\u00f6st die Funktion w\u00e4hrend ihrer Ausf\u00fchrung eine <code>Exception<\/code> aus, welche dann vom Aufrufer behandelt werden muss.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Der-klassische-Exception-Test-mit-JUnit-4\"><\/span>Der klassische Exception Test mit JUnit 4<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Der einfachste Ansatz zum Testen dieses Verhaltens sieht dann so aus, dass man die Funktion aufruft und in einem <code>catch<\/code>-Block pr\u00fcft, dass die Exception tats\u00e4chlich geworfen wurde.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Exception Test mit try-catch\">@Test\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  try {\r\n\r\n    \/\/ call function\r\n\r\n    unitUnderTest.executeFunction(input);\r\n\r\n    fail();     \/\/ ensure that this point is never reached\r\n\r\n  } catch {Exception e) {\r\n\r\n    assertThat(e, is(EXPECTED_EXCEPTION));\r\n\r\n  }\r\n\r\n}\r\n\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Der-Exception-Test-mit-Annotation\"><\/span>Der Exception Test mit Annotation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Wie man im obigen Beispiel sehen kann, ist das mit einigem Boilerplate-Code verbunden, bei dem auch nicht selten Fl\u00fcchtigkeitsfehler auftreten, welche leicht dazu f\u00fchren, funktionale Fehler zu verdecken. Um diesem Umstand entgegenzuwirken wurde mit JUnit 4.0 nun ein Mechanismus eingef\u00fchrt, der die Pr\u00fcfung auf eine erwartete Exception in das Framework verlagert, welches den Test ausf\u00fchrt. Daf\u00fcr muss diesem in der <code>@Test<\/code>-Annotation mitgeteilt werden, welche <code>Exception<\/code>-Klasse erwartet wird. Tritt solch eine Exception nicht auf, schl\u00e4gt der Testfall fehl.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Exception Test mit Annotation\">@Test(expected=Exception.class)\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ call function\r\n\r\n  unitUnderTest.executeFunction(input);\r\n\r\n}\r\n\r\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Der-Exception-Test-mit-Rule\"><\/span>Der Exception Test mit Rule<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Mithilfe der Annotation wird nun zwar die m\u00fchsame Kleinarbeit dem JUnit Framework \u00fcberlassen, daf\u00fcr verliert man aber auch einen Gro\u00dfteil an Flexibilit\u00e4t und Genauigkeit. Es kann damit n\u00e4mlich nur getestet werden, dass an irgend einer Stelle in der Ausf\u00fchrung <em>der Test-Methode<\/em> eine Exception eines bestimmten Typs ausgel\u00f6st wird. Alle weiteren Details der konkreten Exception-Instanz bleiben ungepr\u00fcft.<\/p>\n<p>Nach der Einf\u00fchrung des Konzepts der <code>Rules<\/code> als leicht zu erweiternde Kontrollelemente des Ausf\u00fchrungskontextes von Unit-Tests wurde mit der Version 4.7 die <code>ExpectedException<\/code>-Rule bereitgestellt, um sehr spezifisch die konkreten Eigenschaften von ausgel\u00f6sten Exceptions zu testen.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Exception Test mit Rule\">@Rule\r\n\r\npublic ExpectedException thrown = ExpectedException.none(); \/\/ initially, expect no exception\r\n\r\n@Test\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ after this point, a matching exception is expected\r\n\r\n  thrown = ExpectedException.expect(is(EXPECTED_EXCEPTION));\r\n\r\n  \/\/ call function\r\n\r\n  unitUnderTest.executeFunction(input);\r\n\r\n}\r\n\r\n<\/pre>\n<p>Dieses neue Idiom wird nunmehr f\u00fcr s\u00e4mtliche Exception-Tests empfohlen, da es weniger fehleranf\u00e4llig ist als das erste und viel ausdrucksst\u00e4rker als das zweite.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Aspekte-des-Verhaltens-im-Ausnahmefall\"><\/span>Aspekte des Verhaltens im Ausnahmefall<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Insbesondere bei Tests des Verhaltens einer Unit im Fall einer Ausnahmesituation muss man sehr genau \u00fcberlegen, welche Aspekte des gesamten Verhaltens wirklich relevant sind.<\/p>\n<ul>\n<li>Kann es eine beliebige Exception sein oder muss es ein bestimmter Typ sein?<\/li>\n<li>Muss die Instanz besondere Attribute haben, eine bestimmte Nachricht, einen Ausl\u00f6ser (cause), einen Fehlercode o.\u00e4.?<\/li>\n<li>Wie weit wurde die interne Funktion bereits abgearbeitet?<\/li>\n<li>Wurden Daten erzeugt oder Seiteneffekte ausgel\u00f6st?<\/li>\n<li>Wurden Ressourcen allokiert und auch wieder freigegeben?<\/li>\n<\/ul>\n<p>Da eine Funktion beim Werfen einer Exception rein technisch keinen R\u00fcckgabewert mehr liefern kann, nimmt die Exception selbst nun den Platz des Ergebnisses ein. Aber auch die Interaktion mit den Kollaborateuren ist weiterhin ein Teil des Verhaltens.<\/p>\n<p>Dar\u00fcber hinaus mag es in einer einzelnen Test-Methode au\u00dfer dem eigentlichen Testablauf auch noch hilfreich sein, eventuelle Aufr\u00e4umarbeiten durchzuf\u00fchren, die so spezifisch sind, dass sie in einer allgemeinen mit <code>@After<\/code> annotierten Methode nicht sinnvoll unterzubringen w\u00e4ren.<\/p>\n<p>In der klassischen Variante kann man auf all diese Details sehr spezifisch eingehen.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Spezifischer Exception Test mit try-catch\">@Test\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ fails if any exception is thrown before this point\r\n\r\n  try {\r\n\r\n    \/\/ call function\r\n\r\n    unitUnderTest.executeFunction(input);\r\n\r\n    fail();     \/\/ fails, if no exception is thrown\r\n\r\n  } catch {ExpectedExceptionType e) {   \/\/ fails if type not correct\r\n\r\n    assertSpecificExceptionAttributes(e);   \/\/ fails if attributes not correct\r\n\r\n    verifySpecificColaboratorInteractions();    \/\/ fails if interactions not correct\r\n\r\n  }\r\n\r\n  \/\/ teardown\r\n\r\n  specificCleanup();\r\n\r\n}\r\n\r\n<\/pre>\n<p>Das zweite Idiom mit Spezifikation der erwarteten Exception-Klasse bietet leider tats\u00e4chlich kaum mehr als genau das.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Spezifischer Exception Test mit Annotation\">@Test(expected=ExpectedExceptionType.class)  \/\/ fails if no Exception or wrong type is thrown\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ won't fail if ExpectedExceptionType is thrown before this point\r\n\r\n  \/\/ call function\r\n\r\n  unitUnderTest.executeFunction(input);\r\n\r\n  \/\/ won't fail if any attribute differs from the specification\r\n\r\n  \/\/ won't fail if any interaction differst from the specification\r\n\r\n  \/\/ teardown\r\n\r\n  specificCleanup();    \/\/ will never be executed\r\n\r\n}\r\n\r\n<\/pre>\n<p>Dagegen bietet das aktuell empfohlene Verfahren zwar eine komfortable und flexible Schnittstelle, die Details der geworfenen Exception zu verifizieren; sonstige Pr\u00fcfungen und Nacharbeiten erm\u00f6glicht sie aber nicht.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Spezifischer Exception Test mit Rule\">@Rule\r\n\r\npublic ExpectedException thrown = ExpectedException.none(); \/\/ initially, expect no exception\r\n\r\n@Test\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ fails if any exception is thrown before this point\r\n\r\n  thrown = ExpectedException\r\n\r\n    .expect(ExpectedExceptionType.class)    \/\/ fails if no Exception or wrong type is thrown\r\n\r\n    .expect(is(EXPECTED_EXCEPTION))         \/\/ fails if matcher won't match the exception\r\n\r\n    .expectMessage(\"specific error\")        \/\/ applies containsString Matcher\r\n\r\n    .expectMessage(is(\"specific error\"))    \/\/ fails if matcher won't match the message\r\n\r\n    .expectCause(is(EXPECTED_CAUSE));       \/\/ fails if matcher won't match the cause\r\n\r\n  \/\/ call function\r\n\r\n  unitUnderTest.executeFunction(input);\r\n\r\n  \/\/ won't fail if any interaction differst from the specification\r\n\r\n  \/\/ teardown\r\n\r\n  specificCleanup();    \/\/ will never be executed\r\n\r\n}\r\n\r\n<\/pre>\n<h2><span class=\"ez-toc-section\" id=\"Functional-Interfaces-to-the-rescue\"><\/span>Functional Interfaces to the rescue<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Was also nun? Muss man wieder ganz zum Anfang zur\u00fcck, wenn man wirklich richtig testen will, oder muss man mit den blinden Flecken leben, die das Framework nicht so recht durchdringt?<\/p>\n<p>So schlimm ist es zum Gl\u00fcck nicht.<\/p>\n<p>Mit einer sehr \u00fcberschaubaren selbstgeschriebenen Erweiterung kann man auch die <code>ExpectedException<\/code> Rule dazu bringen, die gew\u00fcnschten Aktivit\u00e4ten nach dem Pr\u00fcfen der geworfenen Exception auszuf\u00fchren. Das Konzept der <code>Functional Interfaces<\/code> in Java 8 gibt uns daf\u00fcr eine komfortable und \u00fcbersichtliche Syntax an die Hand.<\/p>\n<p>Der Trick beruht darauf, dass die Rule zum \u00dcberpr\u00fcfen der <code>Exception<\/code>-Instanz beliebige <code>Matcher<\/code> entgegennimmt und diese aufruft. Wir bauen also einen leichtgewichtigen Adapter, der als <code>Matcher<\/code> auftritt und seinerseits ein <code>Runnable<\/code> aufnimmt, das er dann ausf\u00fchrt. Und wenn man das <code>Runnable<\/code> Interface dann noch in einer Ableitung mit ein bisschen Exception-Handling erg\u00e4nzt, lassen sich auch Methodenaufrufe mit checked Exceptions in der Signatur problemlos in einer Lambda verwenden.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Spezifischer Exception Test mit Rule\">@Rule\r\n\r\npublic void ExpectedException thrown = ExpectedException.none(); \/\/ initially, expect no exception\r\n\r\n@Test\r\n\r\npublic void functionReturnsCorrectResult() {\r\n\r\n  \/\/ setup\r\n\r\n  prepareUnitState();   \/\/ initialize unitUnderTest with state and colaborators\r\n\r\n  prepareColaboratorBehaviour();\r\n\r\n  Object input = prepareInput();\r\n\r\n  \/\/ fails if any exception is thrown before this point\r\n\r\n  thrown = ExpectedException\r\n\r\n    .expect(is(EXPECTED_EXCEPTION))         \/\/ fails if matcher won't match the exception\r\n\r\n    .expect(afterException(() -&gt; {\r\n\r\n      verifySpecificColaboratorInteractions();  \/\/ fails if interactions not correct, may throw checked Exception\r\n\r\n      \/\/ teardown\r\n\r\n      specificCleanup();\r\n\r\n    }));\r\n\r\n  \/\/ call function\r\n\r\n  unitUnderTest.executeFunction(input);\r\n\r\n}\r\n\r\npublic static PerformAfterException afterException(Runnable runnable) {\r\n\r\n  return new PerformAfterException(runnable);\r\n\r\n}\r\n\r\npublic static class PerformAfterException extends TypeSafeMatcher&lt;Throwable&gt; {\r\n\r\n  private final CheckedRunnable&lt;?&gt; runnable;\r\n\r\n  public PerformAfterException(CheckedRunnable&lt;?&gt; runnable) {\r\n\r\n    this.runnable = runnable;\r\n\r\n  }\r\n\r\n  @Override\r\n\r\n  public void describeTo(Description description) {\r\n\r\n    description.appendText(\"Runnable should be performed without errors\");\r\n\r\n  }\r\n\r\n  @Override\r\n\r\n  protected boolean matchesSafely(Throwable item) {\r\n\r\n    if (runnable != null) {\r\n\r\n      runnable.run();\r\n\r\n    }\r\n\r\n    return true;    \/\/ the result could also be determined with a Callable&lt;Boolean&gt;\r\n\r\n  }\r\n\r\n}\r\n\r\n@FunctionalInterface\r\n\r\npublic interface CheckedRunnable&lt;E extends Exception&gt; extends Runnable {\r\n\r\n  @Override\r\n\r\n  default void run() throws RuntimeException {\r\n\r\n    try {\r\n\r\n      runChecked();\r\n\r\n    } catch (Exception ex) {\r\n\r\n      throw new RuntimeException(ex);\r\n\r\n    }\r\n\r\n  }\r\n\r\n  void runChecked() throws E;\r\n\r\n}\r\n\r\n<\/pre>\n<p>Die Adapter-Klasse und die statische Factory-Methode lassen sich leicht in einer Util-Klasse unterbringen, um f\u00fcr alle Tests verf\u00fcgbar zu sein.<\/p>\n<p>Zur Erh\u00f6hung der Wiederverwendbarkeit kann dem Runnable auch die Exception als Parameter \u00fcbergeben werden, wenn man daf\u00fcr ein eigenes Functional Interface definiert. Und letztlich ist auch die Verwendung eines <code>Callable&lt;Boolean&gt;<\/code> anstatt eines Runnable denkbar, um das Ergebnis des Adapters als Matcher zu bestimmen. Dann m\u00fcsste kein AssertionError innerhalb ausgel\u00f6st werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Laufe der Zeit hat das Testing Framework JUnit 4 immer raffiniertere Verfahren angeboten, um das Verhalten in Ausnahmef\u00e4llen (Exceptions) zu testen. Um aber auch mit der aktuellen Methode alle relevanten Aspekte abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.<\/p>\n","protected":false},"author":25,"featured_media":15964,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[69],"service":[420],"coauthors":[{"id":25,"display_name":"Sebastian Schmidt","user_nicename":"sschmidt"}],"class_list":["post-21056","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-digital-quality","service-apps"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019] - inovex GmbH<\/title>\n<meta name=\"description\" content=\"Um mit dem aktuellen Test Framework JUnit 4 alle relevanten Aspekte des Exception Testing abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019] - inovex GmbH\" \/>\n<meta property=\"og:description\" content=\"Um mit dem aktuellen Test Framework JUnit 4 alle relevanten Aspekte des Exception Testing abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-25T08:00:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-12-01T07:42:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Sebastian Schmidt\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing-1024x576.png\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sebastian Schmidt\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"7\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Sebastian Schmidt\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\"},\"author\":{\"name\":\"Sebastian Schmidt\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/a2ffffeaeaa18b9961297ca47e5f3799\"},\"headline\":\"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019]\",\"datePublished\":\"2017-04-25T08:00:02+00:00\",\"dateModified\":\"2022-12-01T07:42:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\"},\"wordCount\":910,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png\",\"keywords\":[\"Digital Quality\"],\"articleSection\":[\"Applications\",\"General\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\",\"url\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\",\"name\":\"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019] - inovex GmbH\",\"isPartOf\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png\",\"datePublished\":\"2017-04-25T08:00:02+00:00\",\"dateModified\":\"2022-12-01T07:42:09+00:00\",\"description\":\"Um mit dem aktuellen Test Framework JUnit 4 alle relevanten Aspekte des Exception Testing abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png\",\"width\":1920,\"height\":1080,\"caption\":\"JUnit 4: A white warning sign with exclamation mark in a bright red surrounding\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.inovex.de\/de\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019]\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.inovex.de\/de\/#website\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.inovex.de\/de\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.inovex.de\/de\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\/\/www.inovex.de\/de\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/inovexde\",\"https:\/\/x.com\/inovexgmbh\",\"https:\/\/www.instagram.com\/inovexlife\/\",\"https:\/\/www.linkedin.com\/company\/inovex\",\"https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/a2ffffeaeaa18b9961297ca47e5f3799\",\"name\":\"Sebastian Schmidt\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/5f905a8b3627c2eb15cdb285c29fe6cf\",\"url\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Avatar_3000-scaled-96x96.jpg\",\"contentUrl\":\"https:\/\/www.inovex.de\/wp-content\/uploads\/Avatar_3000-scaled-96x96.jpg\",\"caption\":\"Sebastian Schmidt\"},\"url\":\"https:\/\/www.inovex.de\/de\/blog\/author\/sschmidt\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019] - inovex GmbH","description":"Um mit dem aktuellen Test Framework JUnit 4 alle relevanten Aspekte des Exception Testing abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/","og_locale":"de_DE","og_type":"article","og_title":"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019] - inovex GmbH","og_description":"Um mit dem aktuellen Test Framework JUnit 4 alle relevanten Aspekte des Exception Testing abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.","og_url":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2017-04-25T08:00:02+00:00","article_modified_time":"2022-12-01T07:42:09+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png","type":"image\/png"}],"author":"Sebastian Schmidt","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing-1024x576.png","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Sebastian Schmidt","Gesch\u00e4tzte Lesezeit":"7\u00a0Minuten","Written by":"Sebastian Schmidt"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/"},"author":{"name":"Sebastian Schmidt","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/a2ffffeaeaa18b9961297ca47e5f3799"},"headline":"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019]","datePublished":"2017-04-25T08:00:02+00:00","dateModified":"2022-12-01T07:42:09+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/"},"wordCount":910,"commentCount":2,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png","keywords":["Digital Quality"],"articleSection":["Applications","General"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/","url":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/","name":"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019] - inovex GmbH","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png","datePublished":"2017-04-25T08:00:02+00:00","dateModified":"2022-12-01T07:42:09+00:00","description":"Um mit dem aktuellen Test Framework JUnit 4 alle relevanten Aspekte des Exception Testing abdecken zu k\u00f6nnen, ist eine kleine Erweiterung notwendig.","breadcrumb":{"@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2017\/04\/junit4-exception-testing.png","width":1920,"height":1080,"caption":"JUnit 4: A white warning sign with exclamation mark in a bright red surrounding"},{"@type":"BreadcrumbList","@id":"https:\/\/www.inovex.de\/de\/blog\/exception-testing-junit-4\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"JUnit 4: Zeitgem\u00e4\u00dfes Exception Testing [Update M\u00e4rz 2019]"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/a2ffffeaeaa18b9961297ca47e5f3799","name":"Sebastian Schmidt","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/image\/5f905a8b3627c2eb15cdb285c29fe6cf","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/Avatar_3000-scaled-96x96.jpg","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/Avatar_3000-scaled-96x96.jpg","caption":"Sebastian Schmidt"},"url":"https:\/\/www.inovex.de\/de\/blog\/author\/sschmidt\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/21056","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=21056"}],"version-history":[{"count":2,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/21056\/revisions"}],"predecessor-version":[{"id":36654,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/21056\/revisions\/36654"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/15964"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=21056"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=21056"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=21056"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=21056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}