在上一篇文章《探索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,现在我们来看看该方法体中的代码:
- 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实现类本身也能很方便地被复用。
原文链接:http://www.blogjava.net/jiangshachina/archive/2011/12/24/366801.html
【编辑推荐】
                分享名称:探索JUnit4扩展:使用Rule
                
                本文路径:http://www.csdahua.cn/qtweb/news37/341037.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网