探索JUnit4扩展:使用Rule

开发 后端
本文将使用JUnit4.7才开始引入的扩展方式--Rule来实现相同的扩展功能。使用Rule对JUnit进行扩展,能够避免对默认Runner的扩展,为测试类添加或移除Rule十分方便,而且Rule实现类本身也能很方便地被复用。

在上一篇文章《探索JUnit4扩展:扩展Runner》中,讨论了一种扩展JUnit4的方式,即,直接修改Test Runner的实现(BlockJUnit4ClassRunner)。但这种方法显然不便于灵活地添加或删除扩展功能。本文将使用JUnit4.7才开始引入的扩展方式--Rule来实现相同的扩展功能。(2010.12.25***更新)

1. Rule

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

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

  1. protected Statement methodBlock(FrameworkMethod method) {  
  2. Object test;  
  3. try {  
  4. test= new ReflectiveCallable() {  
  5. @Override 
  6. protected Object runReflectiveCall() throws Throwable {  
  7. return createTest();  
  8. }  
  9. }.run();  
  10. catch (Throwable e) {  
  11. return new Fail(e);  
  12. }  
  13.  
  14. Statement statement= methodInvoker(method, test);  
  15. statement= possiblyExpectingExceptions(method, test, statement);  
  16. statement= withPotentialTimeout(method, test, statement);  
  17. statement= withBefores(method, test, statement);  
  18. statement= withAfters(method, test, statement);  
  19. statement= withRules(method, test, statement);  
  20. return statement;  

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

2. TestLogRule

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

  1. public class TestLogRule implements TestRule {  
  2. private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss_SSS");  
  3. @Override 
  4. public Statement apply(Statement base, Description description) {  
  5. TestLogger testLogger = description.getAnnotation(TestLogger.class);  
  6. if (testLogger != null) {  
  7. StringBuilder log = new StringBuilder(format.format(new Date()));  
  8. log.append(" ").append(description.getClassName()).append("#")  
  9. .append(description.getMethodName()).append(": ")  
  10. .append(testLogger.log());  
  11. System.out.println(log.toString());  
  12. }  
  13. return base;  
  14. }  

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

3. 使用Rule的CalculatorTest

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

  1. public class CalculatorTest {  
  2. private static Calculator calculator = null;  
  3. @Rule 
  4. public TestLogRule testLogRule = new TestLogRule();  
  5. @BeforeClass 
  6. public static void createCalculator() {  
  7. calculator = new Calculator();  
  8. }  
  9. @Test 
  10. @TestLogger(log = "a simple division")  
  11. public void simpleDivide() {  
  12. int value = calculator.divide(82);  
  13. Assert.assertTrue(value == 4);  
  14. }  
  15. @Test(expected = ArithmeticException.class)  
  16. @TestLogger(log = "divided by zero, and an ArithmeticException thrown.")  
  17. public void dividedByZero() {  
  18. calculator.divide(80);  
  19. }  

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

  1. @Rule 
  2. public TestLogRule testLogRule = new TestLogRule(); 

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

4. 小结

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

原文链接:http://www.blogjava.net/jiangshachina/archive/2011/12/24/366801.html

【编辑推荐】

  1. Java进行HTML数据采集:浅谈强大的group正则
  2. 利用JavaMail API 解析MIME
  3. 详细解析Java中抽象类和接口的区别
  4. Cinch和Sysmon发布 Java辅助开发工具
  5. 解读Java环境变量配置
责任编辑:林师授 来源: Sha Jiang的博客
相关推荐

2011-12-26 10:49:27

JavaJUnitRunner

2009-06-08 19:59:09

EclipseJUnit单元测试

2009-06-08 19:57:29

EclipseJUnit4单元测试

2009-06-08 20:04:06

EclipseJUnit4单元测试

2024-06-07 09:19:00

AIjson字符串

2011-12-01 14:40:18

JUnitJava

2021-04-21 08:56:46

Java注解反射

2012-02-07 09:08:50

Feed4JUnitJava

2021-01-07 14:06:30

Spring BootJUnit5Java

2016-09-23 10:20:22

JUnit扩展模型Extension

2014-04-24 09:49:57

Android测试异步任务

2013-01-07 13:54:17

Android开发JUnit单元测试

2023-01-06 08:06:52

Groovy类型扩展

2011-08-05 09:09:59

英特尔云计算

2024-05-06 11:30:06

2013-06-04 09:49:04

Spring单元测试软件测试

2011-08-24 14:40:50

DROP RULE中文man

2011-08-24 11:31:47

CREATE RULE中文man

2012-04-26 13:46:04

ibmdw

2009-05-04 09:28:36

JunitJava
点赞
收藏

51CTO技术栈公众号