探索JUnit4扩展:使用Rule

编程技术  /  houtizong 发布于 3年前   72

        在上一篇文章中,讨论了使用Runner扩展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

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

TestLogRule.java

package com.bijian.study;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import org.junit.rules.TestRule;import org.junit.runner.Description;import org.junit.runners.model.Statement;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。

CalculatorTest.java

package com.bijian.study;import org.junit.Assert;import org.junit.BeforeClass;import org.junit.Rule;import org.junit.Test;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之外,还多了两行代码

@Rulepublic TestLogRule testLogRule = new TestLogRule();

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

 

4. 小结

        使用Rule对JUnit进行扩展,能够避免对默认Runner的扩展,为测试类添加或移除Rule十分方便,而且Rule实现类本身也能很方便地被复用。在下一篇博文中将进一步探索Rule的应用。

 

文章来源:http://www.blogjava.net/jiangshachina/archive/2011/12/14/366289.html

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客