探索JUnit4扩展:扩展Runner
在使用JUnit的过程中,大家可能会对JUnit进行一些扩展。本文中的示例为JUnit4定义了一个新的Annotation,并相应地对已有的Runner进行扩展,使其能够解析新引入的Annotation。(2011.12.25***更新)
本文臆造了一个示例,会在执行单元测试方法之前,自动地为单元测试方法打印日志。该示例会为JUnit定义一个新的Annotation用于指定要打印的日志内容,并对JUnit默认提供的Runner实现BlockJUnit4ClassRunner进行扩展,使其能够识别这个新的Annotation。
1. 定义Annotation
TestLogger是一个作用于方法的Annotation,它只有一个属性,用于指定日志的内容,其代码如下所示,
- @Target({ ElementType.METHOD })
- @Retention(RetentionPolicy.RUNTIME)
- public @interface TestLogger {
- public String log() default "";
- }
2. 扩展Runner
JUnit提供了若干个Runner的实现,如BlockJUnit4ClassRunner,Suite,其中BlockJUnit4ClassRunner用来执行单个测试用例类。LoggedRunner将扩展BlockJUnit4ClassRunner,覆写其中的methodBlock()方法。新的methodBlock()方法会在一开始试图获取被执行测试方法中的TestLogger Annotation,如果存在的话,就会打印出指定的日志,每行日志以当时的执行时间与完整方法名作为前缀。该类的代码如下所示,
- public class LoggedRunner extends BlockJUnit4ClassRunner {
- private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss_SSS");
- public LoggedRunner(Class<?> klass) throws InitializationError {
- super(klass);
- }
- @Override
- protected Statement methodBlock(FrameworkMethod method) {
- Method classMethod = method.getMethod();
- TestLogger loggerAnnotation = classMethod.getAnnotation(TestLogger.class);
- if (loggerAnnotation != null) {
- StringBuilder log = new StringBuilder(format.format(new Date()));
- log.append(" ").append(classMethod.getDeclaringClass().getName())
- .append("#").append(classMethod.getName()).append(": ")
- .append(loggerAnnotation.log());
- System.out.println(log.toString());
- }
- return super.methodBlock(method);
- }
- }
3. 应用程序
Calculator是一个简单的应用程序,其中定义了一个除法方法,代码如下所示,
- public class Calculator {
- public int divide(int a, int b) {
- return a / b;
- }
- }
4. 单元测试程序
CalculatorTest是一个简单的单元测试程序,它会使用两种方式对Calculator中的divide()方法进行单元测试。其代码如下所示,
- @RunWith(LoggedRunner.class)
- public class CalculatorTest {
- private static Calculator calculator = null;
- @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特别指定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
【编辑推荐】
相关文章
- JFtp 1.56发布 Java开发的FTP客户端
- Groovy 2.0 RC1发布 JVM动态脚本语言
- Hibernate ORM 4.1.4 发布
- Java开源博客:B3log Solo 0.4.5正式版发布
- Java中finally关键字的使用
- 游戏人生Silverlight:星际竞技场
- Swing使用Substance外观包异常问题
- JDK中的URLConnection参数详解
- 6个可用于托管Java应用的云计算平台
- 动态删除ArrayList中的元素
- JACOB的复制表格与添加空行
- Java调用WMIC命令的方法阻塞
- JavaCore/HeapDump文件及其分析方法
- 开发企业应用系统需要掌握的知识技能
- 我跳槽是因为他们的显示器更大
- Tomcat中部署后JspFactory报异常的解决方案
- Aspose.BarCode for Java 4.5.0发布
- Marvin 1.4.0发布 Java图像处理框架
- Java实例化类的方法
- 关于Java自增操作的原子性