JUnit4相比于JUnit3的一个很大的不同就是可以通过Annotation来组织测试用例,从JUnit4.7开始推荐用户通过@Rule来扩展JUnit完成用户自定义的操作,这种方式的好处在于与JUnit4有很好的一致性,不需要修改默认的Runner,而仅仅是通过@Rule就可以达成扩展JUnit的目的。
注:本文使用的JUnit版本是4.8再更高的版本中使用了@ClassRule对@AfterClass和@AfterClass操作进行了扩展,扩展方法与使用@Rule扩展@Before和@After一致;(将在后面的文章中给出4.10中的方式)
通过@Rule扩展JUnit的步骤包括以下几步:
1)创建个性化的Rule类(该类要实现MethodRule接口);
package extension; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; public class OperateRule implements MethodRule { @Override public Statement apply(final Statement base, final FrameworkMethod method, Object target) { return new Statement() { @Override public void evaluate() throws Throwable { // Before method if (method.getAnnotation(BeforeMethod.class) != null) { System.out.println(((BeforeMethod) method .getAnnotation(BeforeMethod.class)).message()); } base.evaluate(); // After method if (method.getAnnotation(AfterMethod.class) != null) { System.out.println(((AfterMethod) method .getAnnotation(AfterMethod.class)).message()); } } }; } }
2)在测试用例所在的类中加入@Rule,创建public的Rule变量;
package test; import org.junit.Rule; import org.junit.Test; import extension.AfterMethod; import extension.BeforeMethod; import extension.OperateRule; public class RuleTestCase { @Rule public OperateRule rule2 = new OperateRule(); @Test @BeforeMethod(message="test_1 before method") public void test_1() { System.out.println("test_1"); } @Test @AfterMethod(message="test_2 after method") public void test_2() { System.out.println("test_2"); } @Test @BeforeMethod(message="test_3 before method") @AfterMethod(message="test_3 after method") public void test_3() { System.out.println("test_3"); } }
注:
BeforeMethod和AfterMethod Annotation定义如下:
package extension; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface BeforeMethod { public String message() default ""; }
package extension; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AfterMethod { public String message() default ""; }
运行结果如下: