Expecting exceptions in junit 4.5From WikiJava
This is something that can be easily worked around by executing your code embedding it in try/catch statements. but if you do so it's not as neat, and if you use a code coverage tool you'll be cheating it as it won't be able to if your code was run or not.
ExplanationWhen you are writing your unit test cases (which should be every time you write any code), you sometimes arrive to the situation where you want to test if your program throws the exceptions as expected or not. The first impulse is always to embed the calls to your methods ini a try/catch, and to put a fail() command right after the method call. Something like follows: @Test public void testConstructorNull() { try { new DefaultDataSet(null, null, null); fail("null pointer exception was not thrown"); } catch (NullPointerException e) { // success, exception was thrown. } } This works fine, although it's not very elegant style. And it may be confusing to read some code that expects an Junit 4.5 offers us a way better way to do this using the Rules system, that is available in the framework.
In the test class a rule is similar to an AOP function, that modifies how the test methods work, simplifying the writing of the testcases. Each test method will have access to a separate version of the Rule, and can modify it.
Additionally it's possible to write your own rules, which can be included in the junit 4 tests, the only requirement is to implement the This short introduction to Rules was necessary to fully understand the following example. where in my test class, I use one of the Rules predefined in Junit 4.5, the This is how we are going to use the We will define a public field (non static) in the test class, as follows: import org.junit.Rule; import org.junit.rules.ExpectedException; ... @Rule public ExpectedException exception = ExpectedException.none(); This will add the rule for each of the test methods of the class. The Finally we'll have the test method where we want to test the Exception to be thrown to look like this: @Test public void testDefaultDataSet() { exception.expect(NullPointerException.class); new DefaultDataSet(null, null, null); } This will modify the Rule just specifically for the test, and it makes so that the test will fail if (and only if) the test won't throw a Note, that the Test will not fail if the exception will be thrown before the Note also that the Note also the use of the The full codepackage org.wikijava.examples.junit; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.wikijava.examples.junit.Product; import org.wikijava.examples.junit.TestTools; /** * @author Giulio Giraldi */ public class junitExample { private Product product; @Rule public ExpectedException exception = ExpectedException.none(); @Before public void setUp() throws Exception { this.product = TestTools.createRandomProduct(100); } @Test public void testDefaultDataSet() { exception.expect(NullPointerException.class); //We expect an exception thrown from this constructor. new DefaultDataSet(this.product, null, null); } }
Alternative: 'expected' attributeAlternatively, you can also use the expected attribute in @Test annotation:
public class junitExample { private Product product; @Before public void setUp() throws Exception { this.product = TestTools.createRandomProduct(100); } @Test(expected=NullPointerException.class) public void testDefaultDataSet() { new DefaultDataSet(this.product, null, null); } }
|
