< 返回技术文档列表

怎样使用Rule

发布时间:2021-11-07 02:25:24

这期内容当中小编将会给大家带来有关怎样使用Rule,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

讨论一种扩展JUnit4的方式,即,直接修改Test Runner的实现(BlockJUnit4ClassRunner)。但这种方法显然不便于灵活地添加或删除扩展功能。这里将使用JUnit4.7才开始引入的扩展方式--Rule来实现相同的扩展功能。

1. Rule

Rule是JUnit4.7才开始提供的一种扩展方式,它能够替代大部分已有的Runner扩展。JUnit包含两种Rule Annotation:@ClassRule与@Rule。@ClassRule应用于测试类中的静态变量,而@Rule应用于成员变量;相同地是,这些变量必须是TestRule接口的实例,且访问修饰符必须为public。

对BlockJUnit4ClassRunner进行了扩展,被扩展的方法是methodBlock,现在我们来看看该方法体中的代码:

protected Statement methodBlock(FrameworkMethod method) {  Object test;  try {  test= new ReflectiveCallable() {  @Override protected Object runReflectiveCall() throws Throwable {  return createTest();  }  }.run();  } catch (Throwable e) {  return new Fail(e);  }   Statement statement= methodInvoker(method, test);  statement= possiblyExpectingExceptions(method, test, statement);  statement= withPotentialTimeout(method, test, statement);  statement= withBefores(method, test, statement);  statement= withAfters(method, test, statement);  statement= withRules(method, test, statement);  return statement;  }

但在BlockJUnit4ClassRunner中,possiblyExpectingExceptions(),withPotentialTimeout(),withBefores()和withAfters()都已经被标注为过时,JUnit建议使用Rule来替代这些方法的功能。

2. TestLogRule

如第1节所述,Rule Annotation要作用于TestRule接口的实例,那么就要先创建一个TestRule的实现类。

public class TestLogRule implements TestRule {  private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss_SSS");  @Override public Statement apply(Statement base, Description description) {  TestLogger testLogger = description.getAnnotation(TestLogger.class);  if (testLogger != null) {  StringBuilder log = new StringBuilder(format.format(new Date()));  log.append(" ").append(description.getClassName()).append("#")  .append(description.getMethodName()).append(": ")  .append(testLogger.log());  System.out.println(log.toString());  }  return base;  }  }

如上所示,TestLogRule与上篇博文中的LoggedRunner的代码有许多相同之处,功能则都是打印出指定的日志,每行日志又以当时的执行时间与完整方法名作为前缀。

3. 使用Rule的CalculatorTest

下面是新的测试类CalculatorTest,它将不使用BlockJUnit4ClassRunner的扩展LoggedRunner作为测试执行器,所以该类没有使用@RunWith(LoggedRunner.class),那么在执行该测试类时仍然会使用BlockJUnit4ClassRunner。

public class CalculatorTest {  private static Calculator calculator = null;  @Rule public TestLogRule testLogRule = new TestLogRule();  @BeforeClass public static void createCalculator() {  calculator = new Calculator();  }  @Test @TestLogger(log = "a simple division")  public void simpleDivide() {  int value = calculator.divide(8, 2);  Assert.assertTrue(value == 4);  }  @Test(expected = ArithmeticException.class)  @TestLogger(log = "divided by zero, and an ArithmeticException thrown.")  public void dividedByZero() {  calculator.divide(8, 0);  }  }

与上篇博文中的CalculatorTest相比,本文中的CalculatorTest除了没有使用LoggedRunner之外,还多了两行代码:

@Rule public TestLogRule testLogRule = new TestLogRule();

在执行单元测试方法之前,BlockJUnit4ClassRunner会调用TestRule/TestLogRule中的apply()方法,即,会先打印出日志内容。

4. 小结

使用Rule对JUnit进行扩展,能够避免对默认Runner的扩展,为测试类添加或移除Rule十分方便,而且Rule实现类本身也能很方便地被复用。

上述就是小编为大家分享的怎样使用Rule了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注血鸟云行业资讯频道。


/template/Home/Zkeys/PC/Static