Samstag, 15. Oktober 2011

JUnit > 4.10 Rules

It's been a long time ago that I last wrote about JUnit. A number of improvements and releases have been made. There have been lot improvements around the topic JUnit rules added. Today I had little bit free time to look into this new JUnit features.

Class Rules
Now there are also class rules in JUnit. A class rule extends the idea of test method-level rules and can be used to add logic, which should be invoked for or after all test methods. A simple use-case could be, when you need a HTTP server in the test, you could have a class rule to start and stop the server. Here a simple code snippet that starts and stops a HTTP server.

import org.junit.ClassRule;
import org.junit.Test;
public class ServerTest {
@ClassRule
public static ServerRule serverRule = new ServerRule();
@Test
public void invokeServletWithRequestOne()
{
}
@Test
public void invokeServletWithRequestTwo()
{
}
}
view raw ServerTest.java hosted with ❤ by GitHub


Test Sequence
  1. Start HTTP Server
  2. Run Test : invokeServletWithRequestOne()
  3. Run Test : invokeServletWithRequestTwo()
  4. Stop HTTP Server


Composition of JUnit Rules with RuleChain Feature
In JUnit 4.10 now you can order rules via a rule chain. This is really nice to reuse rules and combine them. Here a simple RuleChain code snippet.

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
public class ServletTest {
// Starts and Stops the Jetty HTTP Server
ServerRule startServerRule = new ServerRule();
// Creates a SUT servlet instance add it
// and remove it from the Jetty Server.
ServletRule servletRule = new ServletRule(startServerRule.server);
@Rule
public TestRule chain = RuleChain
.outerRule(startServerRule)
.around(servletRule);
@Test
public void invokeServletWithRequestOne()
{
}
@Test
public void invokeServletWithRequestTwo()
{
}
}


Test Sequence
  1. Start new Jetty Server (rule = ServerRule)
  2. Create new Servlet Instance and add it to the Server (rule = ServletRule)
  3. Run Test : invokeServletWithRequestOne()
  4. Remove Servlet from Server (rule = ServletRule)
  5. Stop Jetty Server (rule = ServerRule)
  6. Start new Jetty Server (rule = ServerRule)
  7. Create new Servlet Instance and add it to the Server (rule = ServletRule)
  8. Run Test : invokeServletWithRequestTwo()
  9. Remove Servlet from Server (rule = ServletRule)
  10. Stop Jetty Server (rule = ServerRule)


Interface MethodRule is deprecated
The type MethodRule is now deprecated because the name makes no sense anymore because now we have class and method-level rules. A rule now should be of the type TestRule.

Thanks
Thanks at David Saff and Kent Beck for the work on JUnit and the cool rule features we have now in JUnit.

Links