Clean test classes using JUnit’s rules

2 minute read

A couple of days ago I discovered the beauty of JUnit’s TestRules while searching for an easy way to set a time-out on all tests in a testcase. JUnit has a built-in rule for this called Timeout. You can set this rule for every test in your class by setting the timeout in a field like this:

```java Setting a Timeout Rule View the Javadoc

public class MyTest {

public MethodRule globalTimeout= new Timeout(20);

public void someTest() {
Another gem is the `ExpectedException` rule, which allows you to inspect a thrown exception in several ways.

```java Inspecting excptions View the Javadoc
public static class HasExpectedException {
	public ExpectedException thrown= ExpectedException.none();

	public void throwsNothing() {
	// no exception expected, none thrown: passes.
    public void throwsNullPointerException() {
		throw new NullPointerException();
	public void throwsNullPointerExceptionWithMessage() {
		throw new NullPointerException("What happened?");

The great thing is, it’s super easy to extend one of these rules.

In Crawljax, another project I’m currently working on, I wanted a Jetty server to start before I the tests run, and to shut it down afterwards. I could do this using a @BeforeClass method and then clean it up in the @AfterClass method but that doesn’t make it reusable in other classes. To make it reusable I could put it in an abstract class that just has the setup and teardown methods and inherit that class in the classes where I need the server. However, that can lead to weird class hierarchies that don’t make any sense. Again, JUnit’s rules come to the rescue. There’s the ExternalResource that allows you to setup resources before tests, and tear them down afterwards. I inherited this class to provide my Jetty server.

```java Rule to start a Jetty Server View on GitHub public class RunWithWebServer extends ExternalResource {

private final Resource resource;

private int port;
private URL demoSite;
private Server server;
private boolean started;

 * @param classPathResource
 *            The name of the resource. This resource must be on the test or regular classpath.
public RunWithWebServer(String classPathResource) {
	resource = Resource.newClassPathResource(classPathResource);

protected void before() throws Throwable {
	server = new Server(0);
	ResourceHandler handler = new ResourceHandler();
	this.port = server.getConnectors()[0].getLocalPort();
	this.demoSite = new URL("http", "localhost", port, "/");
	this.started = true;

protected void after() {
	try {
		if (server != null) {
	} catch (Exception e) {
		throw new RuntimeException("Could not stop the server", e);

// Some getters for the fields } ```

The class starts the Jetty server using the given resource as the web folder. Tests can then use this rule to obtain a real URL to test with:

```java Using the webserver. Usage example public void SomeWebTest {

public static final RunWithWebServer SERVER = new RunWithWebServer("/site/crawler");

public void test() {
	URL url = SERVER.getSiteUrl();

} ```

There are more built-in rules in JUnit like:

  • The TemporaryFolder That creates a temporary folder for you,
  • the Verifier that can verify some invariant after each test method,
  • and more! Checkout the JUnit wiki to learn more of them.

Have fun!