JUnit 4: Set up things in a test suite before tests are run (like a test’s @BeforeClass method, just for a test suite)

The answer is now to create a @ClassRule within your suite. The rule will be invoked before or after (depending on how you implement it) each test class is run. There are a few different base classes you can extend/implement. What is nice about class rules is that if you do not implement them as anonymous classes then you can reuse the code!

Here is an article about them: http://java.dzone.com/articles/junit-49-class-and-suite-level-rules

Here is some sample code to illustrate their use. Yes, it is trivial, but it should illustrate the life-cycle well enough for you to get started.

First the suite definition:

import org.junit.*;
import org.junit.rules.ExternalResource;
import org.junit.runners.Suite;
import org.junit.runner.RunWith;


@RunWith( Suite.class )
@Suite.SuiteClasses( { 
    RuleTest.class,
} )
public class RuleSuite{

    private static int bCount = 0;
    private static int aCount = 0;

    @ClassRule
    public static ExternalResource testRule = new ExternalResource(){
            @Override
            protected void before() throws Throwable{
                System.err.println( "before test class: " + ++bCount );
                sss = "asdf";
            };

            @Override
            protected void after(){
                System.err.println( "after test class: " + ++aCount );
            };
        };


    public static String sss;
}

And now the test class definition:

import static org.junit.Assert.*;

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExternalResource;

public class RuleTest {

    @Test
    public void asdf1(){
        assertNotNull( "A value should've been set by a rule.", RuleSuite.sss );
    }

    @Test
    public void asdf2(){
        assertEquals( "This value should be set by the rule.", "asdf", RuleSuite.sss );
    }
}

Leave a Comment