Development

Rules in JUnit

From version 4.7, JUnit introduced a new concept called Rules which really helpful. Rules allow very flexible addition or redefinition of the behavior of each test method in a test class.  Testers can reuse or extend one of the provided Rules below, or write their own. Here are some of the rules:

  • TemporaryFolder Rule allows creation of files and folders that are guaranteed to be deleted when the test method finishes (whether it passes or fails).

public static class HasTempFolder {

@Rule

public TemporaryFolder folder= new TemporaryFolder();

 

@Test

public void testUsingTempFolder() throws IOException {

File createdFile= folder.newFile(“myfile.txt”);

File createdFolder= folder.newFolder(“subfolder”);

// …

}

}

  • ExternalResource is a base class for Rules (like TemporaryFolder) that set up an external resource before a test (a file, socket, server, database connection, etc.), and guarantee to tear it down afterward.

 

public static class UsesExternalResource {

Server myServer = new Server();

 

@Rule

public ExternalResource resource = new ExternalResource() {

@Override

protected void before() throws Throwable {

myServer.connect();

};

 

@Override

protected void after() {

myServer.disconnect();

};

};

 

@Test public void testFoo() {

new Client().run(myServer);

}

}

  • ErrorCollector Rule allows execution of a test to continue after the first problem is found (for example, to collect _all_ the incorrect rows in a table, and report them all at once).
  • Timeout Rule applies the same timeout to all test methods in a class
  • ExpectedException Rule allows in-test specification of expected exception types and messages.

In version 4.9, JUnit introduced Test-class and suite level Rules. The `ClassRule` annotation extends the idea of method-level Rules, adding static fields that can affect the operation of a whole class.  Any subclass of `ParentRunner`, including the standard `BlockJUnit4ClassRunner` and `Suite` classes, will support `ClassRule`s.

In version 4.10, JUnit introduced RuleChain which allows ordering of TestRules.

public static class UseRuleChain {

@Rule

public TestRule chain= RuleChain

.outerRule(new LoggingRule(“outer rule”)

.around(new LoggingRule(“middle rule”)

.around(new LoggingRule(“inner rule”);


@Test

public void example() {

assertTrue(true);

}

}

As it said, testers can reuse or extend existing rule, also can write their own rules. One library System Rules implemented by Marc Philipp and Stefan Birkner is sometimes very useful. The System Rules is a collection of JUnit rules for testing code which uses java.lang.System Class. It can help for testing with System.getProperty, System.setProperty, System.exit, System.getSecurityManager, System.err, System.in, System.out.

For example: in some case, we may let system exit using System.exit(0). But this is regarded by JUnit as an error: junit.framework.AssertionFailedError: Forked Java VM exited abnormally. With System Rules, you can

@Rule

public final ExpectedSystemExit exit = ExpectedSystemExit.none();

 

@Test

public void systemExit(){

exit.expectSystemExitWithStatus(-1);

//… the code will call System.exit()

}

References:

  1. https://raw.github.com/KentBeck/junit/23ffc6baf5768057e366e183e53f4dfa86fbb005/doc/ReleaseNotes4.7.txt
  2. http://stefanbirkner.github.com/system-rules/

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Categories
Follow Us
TwitterLinkedinFacebookYoutubeInstagram