Roy Osherove

View Original

JUnit 4 feels like NUnit with attribute-like syntax

I'm doing Test-Driven-Development with Java course, after having not done one for a long time, and I was browsing through my samples and online to see if anything interesting in JUnit land has happened since last time. And there sure is!

JUnit 4 is out and allows using Java Annotations (Java's version of .NET Attributes if you will) to write tests. No need for inheritance anymore, or to begin test names with 'test". simply use annotations:

Here is an example takes from this blog, which has a more elaborate list of changes with examples:

Test Annotations:

   
@Test public void emptyTest() { stack = new Stack < String > (); assertTrue(stack.isEmpty()); }

(I'm using the cool Code formatter live writer plugin )

Also, you get matching annotations for setup and teardown:

   
public class OutputTest { private File output; @Before public void createOutputFile() { output = new File(...); } @After public void deleteOutputFile() { output.delete(); } @Test public void testSomethingWithFile() { ... } }

For some weird reason, it's possible to put this annotation on multiple methods in the same test fixture, and they will all run in an unknown order. Not sure why that is useful, or at all contributes to readability..

You also get to test for expected exceptions more easily:

   
@Test(expected = IndexOutOfBoundsException. class ) public void testIndexOutOfBoundsException() { ArrayList emptyList = new ArrayList(); Object o = emptyList.get( 0 ); }

Parameterized Tests

One feature I was pretty surprised to see, but rather glad that I saw it, the fact that, a bit like in MbUnit, JUnit 4 has support for tests that can take parameters, and thus being able to run the test multiple times with different inputs.

Differently than JUnit though, you need to create a class for each Parameterized test you'd like to create, and put annotations on the class, and on the source of the parameters (data source, if you will). this allows a more data-driven-testing kind of way, which is a bit like what you can find in VSTS Unit Testing support.

   
@RunWith (value = Parameterized.class) public class StackTest { Stack < Integer > stack; private int number ; public StackTest( int number ) { this. number = number ; } @Parameters public static Collection data() { Object [][] data = new Object [][] { { 1 }, { 2 }, { 3 }, { 4 } }; return Arrays.asList(data); } ... }

Test Suites

Creating Test Suites with JUnit 4 is rather a weird task. You create an empty class with the sole takes of carrying annotations that point to the class list to run:

 

   
@RunWith (Suite.class) @Suite .SuiteClasses({StackTest.class}) public class AllTests { }