I think this question needs an updated answer, since most of the answers here are pretty outdated.
Firstly, the OP question:
I think he pretty well agreed that introducing the concept of expected excepetion into JUnit was a bad move, as this exception could be raised anywhere and it would pass the test. It works if you throw (and claim) very domain-specific exceptions, but I only throw those exceptions when I work on code that should be absolutely flawless - almost APIS will just throw inline exceptions like IllegalArgumentException or IllegalStateException . If the two calls you make can raise these exceptions, then the @ExpectedException annotation will @ExpectedException green test, even if its incorrect line throws an exception!
In this situation, I wrote a class that I am sure many others here wrote that the assertThrows method:
public class Exceptions { private Exceptions(){} public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){ try{ actionThatShouldThrow.run(); fail("expected action to throw " + expectedException.getSimpleName() + " but it did not."); } catch(Exception e){ if ( ! expectedException.isInstance(e)) { throw e; } } } }
this method simply returns if an exception is thrown, which allows you to make further statements / checks in your test.
with java 8 syntax, your test looks very nice. Below is one of the simple tests of our model, which uses the method:
@Test public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() { //setup AxisRange range = new AxisRange(0,100); //act Runnable act = () -> range.setLowerBound(200); //assert assertThrows(IllegalArgumentException.class, act); }
these tests are a little mediocre because the act step does not actually do anything, but I think the meaning is still pretty clear.
There is also a small small library on maven called catch-exception that uses the mockito style syntax to verify that exceptions are thrown. It looks beautiful, but I'm not a fan of dynamic proxies. However, the syntax is so smooth that it remains enticing:
// given: an empty list List myList = new ArrayList(); // when: we try to get the first element of the list // then: catch the exception if any is thrown catchException(myList).get(1); // then: we expect an IndexOutOfBoundsException assert caughtException() instanceof IndexOutOfBoundsException;
Finally, for the situation that I encountered, in order to switch to this thread, there is a way to ignore tests if some conidation is performed.
I'm currently working on getting some DLLs called through a java library loaded via JNA, but our build server is located in ubuntu. I like trying to control this development with JUnit tests - even if they are far from “units” at this point. What I want to do is run the test if I'm on the local machine, but ignore the test if we're on ubuntu. In JUnit 4, there is a condition for this called Assume :
@Test public void when_asking_JNA_to_load_a_dll() throws URISyntaxException { //this line will cause the test to be branded as "ignored" when "isCircleCI" //(the machine running ubuntu is running this test) is true. Assume.assumeFalse(BootstrappingUtilities.isCircleCI()); //an ignored test will typically result in some qualifier being put on the results, //but will also not typically prevent a green-ton most platforms. //setup URL url = DLLTestFixture.class.getResource("USERDLL.dll"); String path = url.toURI().getPath(); path = path.substring(0, path.lastIndexOf("/")); //act NativeLibrary.addSearchPath("USERDLL", path); Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class); //assert assertThat(dll).isNotNull(); }