首页 > 代码库 > JUnit之Rule的使用

JUnit之Rule的使用

简介JUnit之Rule的简单用法。为分析JUnit相关源代码做点准备。

Rule是一个用于测试单元类如MyTest中定义一个域的标注,该域must be public, not static, and a subtype of  org.junit.rules.MethodRule

package org.junit;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Rule {
}

Kent Beck曾经写过一篇文章<Interceptors in JUnit>,虽然最后叫Rule,但仍然起拦截器/Interceptor的作用——即在运行测试的前后添加一些有用的代码。

【注:JUnit4.9开始,MethodRule被deprecated,TestRule取代它。MethodRule接口定义的唯一方法:

Statement apply(Statement base, FrameworkMethod method, Object target);

TestRule的对应物:

Statement apply(Statement base, Description description);

】(严重影响yqj2065阅读4.8.2源代码的心情难过发火

①先为MyRule准备一个Statement 

package myTest.rule;
import static tool.Print.*;//pln(Object)
import org.junit.runners.model.Statement;
public class MyStatement extends Statement {
    private final Statement base;
    public MyStatement( Statement base ) {
        this.base = base;
    }

    @Override public void evaluate() throws Throwable {
        pln( "before...sth..sth" );
        try {
            base.evaluate();
        } finally {
             pln( "after...sth..sth" );
        }
    }
}

②定义MyRule

package myTest.rule;
//import org.junit.runner .Description;
import org.junit.rules.MethodRule;
import org.junit.runners.model.Statement;
import org.junit.runners.model.FrameworkMethod;
public class MyRule implements MethodRule  {
    @Override
    public Statement apply( Statement base, FrameworkMethod method,  Object target ) {
        return new MyStatement( base );
    }
}

③最后在测试单元类MyTest中使用Rule

package myTest.rule;
import org.junit.Rule;
import org.junit.Test;
public class MyTest {
    @Rule
    public MyRule myRule = new MyRule();

    @Test
    public void testCase() {
        System.out.println( "testCase()..." );
    }
}

运行testCase()的输出:

before...sth..sth
testCase()...
after...sth..sth

JUnit之Rule的使用