{"id":3260,"date":"2017-04-01T13:15:38","date_gmt":"2017-04-01T07:45:38","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=3260"},"modified":"2017-04-01T13:15:38","modified_gmt":"2017-04-01T07:45:38","slug":"assert-certain-exception-thrown-junit-4-tests","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/assert-certain-exception-thrown-junit-4-tests\/","title":{"rendered":"JAVA &#8211; How do you assert that a certain exception is thrown in JUnit 4 tests?"},"content":{"rendered":"<ul>\n<li>JUnit provides an option of tracing the exception handling of code. You can test whether the code throws a desired exception or not. The\u00a0expected\u00a0parameter is used along with @Test annotation.<\/li>\n<li>An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions.<\/li>\n<li>Java programming language provides exceptions to deal with errors and other exceptional events in the code.<\/li>\n<li>The biggest advantage of exceptions is that they simply allow you to separate error-handling code from regular code.<\/li>\n<li>This improves the robustness and readability of programs created in Java.<\/li>\n<li>Java provides several techniques to effectively work with exceptions:<\/li>\n<\/ul>\n<ol>\n<ol>try, catch, and finally \u2212 to handle exceptions,<\/ol>\n<ol>try-with-resources statement \u2212 to work with resources,<\/ol>\n<ol>throw\/throws \u2212 to throw and declare exceptions respectively.<\/ol>\n<\/ol>\n<ul>\n<li>In JUnit, we may employ many techniques for testing exceptions including:\n<ol>\n<ol>try-catch idiom<\/ol>\n<ol>With JUnit rule<\/ol>\n<ol>With @Test annotation<\/ol>\n<ol>With catch-exception library<\/ol>\n<ol>With custom annotation<\/ol>\n<ol>With Lambda expression (as of Java 1.8)<\/ol>\n<ol>With AssertJ 3.0.0 for Java 8<\/ol>\n<\/ol>\n<\/li>\n<\/ul>\n<h4 id=\"try-catch-idiom\"><span style=\"color: #800000;\">try-catch idiom<\/span><\/h4>\n<ul>\n<li>This idiom is one of the most popular one, because it was used already in JUnit 3.<\/li>\n<\/ul>\n[pastacode lang=\u201djava\u201d manual=\u201dpublic%20void%20throwsExceptionWhenNegativeNumbersAreGiven()%20%7B%0A%20%20%20%20try%20%7B%0A%20%20%20%20%20%20%20%20calculator.add(%22-1%2C-2%2C3%22)%3B%0A%20%20%20%20%20%20%20%20fail(%22Should%20throw%20an%20exception%20if%20one%20or%20more%20of%20given%20numbers%20are%20negative%22)%3B%0A%20%20%20%20%7D%20catch%20(Exception%20e)%20%7B%0A%20%20%20%20%20%20%20%20assertThat(e)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.isInstanceOf(IllegalArgumentException.class)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20.hasMessage(%22negatives%20not%20allowed%3A%20%5B-1%2C%20-2%5D%22)%3B%0A%20%20%20%20%7D%0A%7D\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n[ad type=\u201dbanner\u201d]\n<p>The above approach is a common pattern. The test will fail when no exception is thrown and the exception itself is verified in a catch clause (in the above example I used the FEST Fluent Assertions) and preferring the approach with ExpectedException rule executes better results<\/p>\n<h4 id=\"with-junit-rule\"><span style=\"color: #ff6600;\"><strong>With JUnit rule<\/strong><\/span><\/h4>\n<p>The same example can be created using ExceptedException rule. The rule must be a public field marked with @Rule annotation. Please note that the \u201cthrown\u201d rule may be reused in many tests.<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201d%40Rule%0Apublic%20ExpectedException%20thrown%20%3D%20ExpectedException.none()%3B%0A%20%0A%40Test%0Apublic%20void%20throwsExceptionWhenNegativeNumbersAreGiven()%20%7B%0A%20%20%20%20%2F%2F%20arrange%0A%20%20%20%20thrown.expect(IllegalArgumentException.class)%3B%0A%20%20%20%20thrown.expectMessage(equalTo(%22negatives%20not%20allowed%3A%20%5B-1%2C%20-2%5D%22))%3B%0A%20%20%20%20%2F%2F%20act%0A%20%20%20%20calculator.add(%22-1%2C-2%2C3%22)%3B%0A%7D\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<p>When the exception isn\u2019t thrown you will get the following message: java.lang.AssertionError: Expected test to throw (an instance of java.lang.IllegalArgumentException and exception with message \u201cnegatives not allowed: [-1, -2]\u201d)<\/p>\n<p>But not all the exception it checks only the type of the exception thrown and then we have to make use @Test annotation.<\/p>\n<h4 id=\"with-annotation\"><strong><span style=\"color: #ff0000;\">With annotation<\/span><\/strong><\/h4>\n[pastacode lang=\u201djava\u201d manual=\u201d%40Test%20(expected%20%3D%20IllegalArgumentException.class)%0Apublic%20void%20throwsExceptionWhenNegativeNumbersAreGiven()%20%7B%0A%20%20%20%20%2F%2F%20act%0A%20%20%20%20calculator.add(%22-1%2C-2%2C3%22)%3B%0A%7D\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<p>When the exception wasn\u2019t thrown you will get the following message: java.lang.AssertionError: Expected exception: java.lang.IllegalArgumentException<\/p>\n<p>Sometimes the approach tempts to expect general Exception, RuntimeException or even a Throwable. And this is considered as a bad practice, because the code may throw exception in other place than actually expected and the test will still pass<\/p>\n<ul>\n<li>With JUnit rule and with annotation: The advantages are,<\/li>\n<\/ul>\n<ol>\n<ol>Error messages when the code does not throw an exception are automagically handled<\/ol>\n<ol>The readability is improved<\/ol>\n<ol>There is less code to be created<\/ol>\n<\/ol>\n<h4 id=\"assertj-assertion\"><strong><span style=\"color: #808000;\">AssertJ assertion<\/span><\/strong><\/h4>\n[pastacode lang=\u201djava\u201d manual=\u201dimport%20static%20org.assertj.core.api.Assertions.*%3B%0A%0A%40Test%0Apublic%20void%20testFooThrowsIndexOutOfBoundsException()%20%7B%0A%20%20Foo%20foo%20%3D%20new%20Foo()%3B%0A%0A%20%20assertThatThrownBy(()%20-%3E%20foo.doStuff())%0A%20%20%20%20%20%20%20%20.isInstanceOf(IndexOutOfBoundsException.class)%3B%0A%7D\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n[ad type=\u201dbanner\u201d]\n<p>It\u2019s better than @Test(expected=IndexOutOfBoundsException.class) because it guarantees the expected line in the test threw the exception and lets you check more details about the exception, such as message, easier:<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dassertThatThrownBy(()%20-%3E%0A%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20throw%20new%20Exception(%22boom!%22)%3B%0A%20%20%20%20%20%20%20%7D)%0A%20%20%20%20.isInstanceOf(Exception.class)%0A%20%20%20%20.hasMessageContaining(%22boom%22)%3B\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<h4 id=\"expectedexception-rule\"><strong><span style=\"color: #0000ff;\">ExpectedException Rule<\/span><\/strong><\/h4>\n<ul>\n<li>Alternatively, use the ExpectedException rule. This rule lets you indicate not only what exception you are expecting, but also the exception message you are expecting:<\/li>\n<\/ul>\n[pastacode lang=\u201djava\u201d manual=\u201d%40Rule%0Apublic%20ExpectedException%20thrown%20%3D%20ExpectedException.none()%3B%0A%0A%40Test%0Apublic%20void%20shouldTestExceptionMessage()%20throws%20IndexOutOfBoundsException%20%7B%0A%20%20%20%20List%3CObject%3E%20list%20%3D%20new%20ArrayList%3CObject%3E()%3B%0A%0A%20%20%20%20thrown.expect(IndexOutOfBoundsException.class)%3B%0A%20%20%20%20thrown.expectMessage(%22Index%3A%200%2C%20Size%3A%200%22)%3B%0A%20%20%20%20list.get(0)%3B%20%2F%2F%20execution%20will%20never%20get%20past%20this%20line%0A%7D\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<p>The expectMessage also lets you use Matchers, which gives you a bit more flexibility in your tests. An example:<\/p>\n[pastacode lang=\u201djava\u201d manual=\u201dthrown.expectMessage(Matchers.containsString(%22Size%3A%200%22))%3B\u201d message=\u201dJava Code\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\n<h4 id=\"combining-rules-with-runwith\"><strong><span style=\"color: #800080;\">Combining Rules with @RunWith<\/span><\/strong><\/h4>\n<ul>\n<li>Beware though that if we combine the rule with certain @RunWith classes, we may get a false positive. Specifically, if you were to run with a class that extends JUnit4ClassRunner, the test would no longer fail. We\u2019d get a false positive.<\/li>\n<li>For example, if you\u2019re using a version of JMock prior to 2.6.0 and use @RunWith(JMock.class) we\u2019ll encounter this. Older versions of the JMock.class extend JUnit4ClassRunner and JUnit4ClassRunner ignores rules. The newer BlockJUnit4ClassRunner supports rules and JMock post 2.6.0 extends this class in JMock.class.<\/li>\n<\/ul>\n[ad type=\u201dbanner\u201d]\n","protected":false},"excerpt":{"rendered":"<p>JAVA &#8211; How do you assert that a certain exception is thrown in JUnit 4 tests? JUnit provides an option of tracing the exception handling of code.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2139],"tags":[6086,6083,6071,6084,3116,6077,6085,6078,6076,6074,6080,6073,6072,6075,6082,6081,6079],"class_list":["post-3260","post","type-post","status-publish","format-standard","hentry","category-java","tag-different-ways-of-testing-exceptions-in-java-and-junit","tag-exception-testing--junit","tag-expected-exception-junit","tag-expectedexception","tag-how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests","tag-java-lang-assertionerror-expected-exception","tag-junit-expected-exceptions-test-7-ways-of-handling-exceptions-in-junit","tag-junit-assert-fail","tag-junit-assertthrown","tag-junit-exception-handling","tag-junit-exceptions-test","tag-junit-expected-exception-annotation","tag-junit-expected-exception-message","tag-junit-expected-exception-rule","tag-testing-custom-exceptions-with-junits-expectedexception","tag-testing-for-expected-exceptions-in-junit","tag-unit-test-assertion"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/3260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=3260"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/3260\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=3260"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=3260"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=3260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}