探索JUnit4扩展:扩展Runner

开发 后端
在使用JUnit的过程中,大家可能会对JUnit进行一些扩展。本文中的示例为JUnit4定义了一个新的Annotation,并相应地对已有的Runner进行扩展,使其能够解析新引入的Annotation。

在使用JUnit的过程中,大家可能会对JUnit进行一些扩展。本文中的示例为JUnit4定义了一个新的Annotation,并相应地对已有的Runner进行扩展,使其能够解析新引入的Annotation。(2011.12.25***更新)

本文臆造了一个示例,会在执行单元测试方法之前,自动地为单元测试方法打印日志。该示例会为JUnit定义一个新的Annotation用于指定要打印的日志内容,并对JUnit默认提供的Runner实现BlockJUnit4ClassRunner进行扩展,使其能够识别这个新的Annotation。

1. 定义Annotation

TestLogger是一个作用于方法的Annotation,它只有一个属性,用于指定日志的内容,其代码如下所示,

  1. @Target({ ElementType.METHOD })  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. public @interface TestLogger {  
  4. public String log() default "";  

2. 扩展Runner

JUnit提供了若干个Runner的实现,如BlockJUnit4ClassRunner,Suite,其中BlockJUnit4ClassRunner用来执行单个测试用例类。LoggedRunner将扩展BlockJUnit4ClassRunner,覆写其中的methodBlock()方法。新的methodBlock()方法会在一开始试图获取被执行测试方法中的TestLogger Annotation,如果存在的话,就会打印出指定的日志,每行日志以当时的执行时间与完整方法名作为前缀。该类的代码如下所示,

  1. public class LoggedRunner extends BlockJUnit4ClassRunner {  
  2.  
  3. private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss_SSS");  
  4.  
  5. public LoggedRunner(Class<?> klass) throws InitializationError {  
  6. super(klass);  
  7. }  
  8.  
  9. @Override 
  10. protected Statement methodBlock(FrameworkMethod method) {  
  11. Method classMethod = method.getMethod();  
  12. TestLogger loggerAnnotation = classMethod.getAnnotation(TestLogger.class);  
  13. if (loggerAnnotation != null) {  
  14. StringBuilder log = new StringBuilder(format.format(new Date()));  
  15. log.append(" ").append(classMethod.getDeclaringClass().getName())  
  16. .append("#").append(classMethod.getName()).append(": ")  
  17. .append(loggerAnnotation.log());  
  18. System.out.println(log.toString());  
  19. }  
  20. return super.methodBlock(method);  
  21. }  

3. 应用程序

Calculator是一个简单的应用程序,其中定义了一个除法方法,代码如下所示,

  1. public class Calculator {  
  2. public int divide(int a, int b) {  
  3. return a / b;  
  4. }  

4. 单元测试程序

CalculatorTest是一个简单的单元测试程序,它会使用两种方式对Calculator中的divide()方法进行单元测试。其代码如下所示,

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

值得注意的是,CalculatorTest特别指定LoggedRunner作为测试执行器(@RunWith(LoggedRunner.class));同时,每个单元测试方法,simpleDivide()与dividedByZero(),都使用了Annotation TestLogger,为其指定日志内容。当执行上述单元测试时,会自动地打印出如下形式的日志内容:

2011-12-13_23:48:38_218 test.CalculatorTest#simpleDivide: a simple division
2011-12-13_23:48:38_218 test.CalculatorTest#dividedByZero: divided by zero, and an ArithmeticException thrown.

5. 小结

通过对BlockJUnit4ClassRunner的扩展,可以让JUnit在运行测试用例时做一些额外的工作。但这种直接修改默认Test Runner的方式并不被提倡,在下一篇文章中将会介绍使用Test Rule来达到相同的扩展目的。

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

【编辑推荐】

  1. 探索JUnit4扩展:使用Rule
  2. Java进行HTML数据采集:浅谈强大的group正则
  3. 多态在 Java 和 C++ 编程语言中的实现比较
  4. 利用JavaMail API 解析MIME
  5. 详细解析Java中抽象类和接口的区别
责任编辑:林师授 来源: Sha Jiangd的博客
相关推荐

2011-12-26 10:38:28

JavaJUnitRule

2011-12-01 14:40:18

JUnitJava

2012-02-07 09:08:50

Feed4JUnitJava

2024-06-07 09:19:00

AIjson字符串

2009-06-08 19:59:09

EclipseJUnit单元测试

2009-06-08 19:57:29

EclipseJUnit4单元测试

2009-06-08 20:04:06

EclipseJUnit4单元测试

2016-09-23 10:20:22

JUnit扩展模型Extension

2011-08-05 09:09:59

英特尔云计算

2024-07-01 12:13:44

2023-01-06 08:06:52

Groovy类型扩展

2024-05-06 11:30:06

2009-08-27 18:04:01

c#扩展方法string

2021-04-21 08:56:46

Java注解反射

2023-01-05 08:09:27

GroovyDSL​

2018-05-31 14:40:33

2009-12-01 10:08:23

WF4属性

2010-06-30 17:15:39

向外扩展SQL Ser

2009-03-16 09:16:13

行为扩展WCF.NET

2009-08-31 14:45:10

C#扩展方法
点赞
收藏

51CTO技术栈公众号