JUnit @Rule Based TestRule Example

0

JUnit uses TestRule objects to alter the behavior of test method. JUnit uses @Rule and @ClassRule annotation to determine the test rules defined.
A test rule can be applied either before each test method or once at the class level depending on whether you have defined the test rule using @Rule or @ClassRule. Multiple TestRules can be applied where each rule modifies an existing statement and returns a new statement thereby bringing the necessary change which in turn is passed to the next test rule. A test rule can be defined either using a field that is a subtype of TestRule or method that returns subtype of TestRule. If a test rule is applied using @Rule, the field or method must be public and non-static.

In the below test class we have defined multiple test rules. There are couple of field level test rules rule1 and rule2, and couple of methods that return TestRule instance.

MultipleTestRulesExample:

package com.javarticles.junit;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class MultipleTestRulesExample {
    @Rule
    public final TestRule rule1 = new TestRule() {
        
        public Statement apply(Statement base, Description description) {
            System.out.println("apply field rule1");
            return base;
        }
    };  
    
    @Rule
    public final TestRule rule2 = new TestRule() {
        
        public Statement apply(Statement base, Description description) {
            System.out.println("apply field rule2");
            return base;
        }
    }; 
    
    @Rule
    public TestRule rule1() {
        return new TestRule() {
            
            public Statement apply(Statement base, Description description) {
                System.out.println("apply method rule1");
                return base;
            }
        }; 
    }
    
    @Rule
    public TestRule rule2() {
        return new TestRule() {
            
            public Statement apply(Statement base, Description description) {
                System.out.println("apply method rule2");
                return base;
            }
        }; 
    }
    
    @BeforeClass
    public static void beforeClass() throws Exception {
        System.out.println("Before class");
    }
    
    @Before
    public void beforeTest() throws Exception {
        System.out.println("Before test");
    }
    
    
    @Test
    public void test1() {   
        System.out.println("test1");
    }
    
    @Test
    public void test2() {   
        System.out.println("test2");
    }
    
    @After
    public void afterTest() throws Exception {
        System.out.println("After test");
    }
    
    @AfterClass
    public static void afterClass() throws Exception {
        System.out.println("After class");
    }    
}

You can see from the output the test rules are applied just before calling the @Before annotated test method. The test rules are applied for each test method.

Output:

Before class
apply method rule1
apply method rule2
apply field rule1
apply field rule2
Before test
test1
After test
apply method rule1
apply method rule2
apply field rule1
apply field rule2
Before test
test2
After test
After class

Field TestRule vs Method TestRule

If you notice in the above test class there are multiple annotated @Rules and we have rules that are defined as fields as well as methods. In such cases the rules defined by methods will be applied first followed by rules defined by fields.

Output:

Before class
apply method rule1
apply method rule2
apply field rule1
apply field rule2
Before test
test1
After test
apply method rule1
apply method rule2
apply field rule1
apply field rule2
Before test
test2
After test
After class

Download the source code

This was an example about TestRules defined using @Rule annotation.

You can download the source code here: junitMultipleTestRulesExample.zip

About Author

Ram's expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring. You can reach him at rsatish.m@gmail.com

Comments are closed.