Junit @Rule

JUnit Rule的两个注解需要用于实现了TestRuleMethodRule接口的成员变量(@Rule)或静态变量(@ClassRule)上。

  • @Rule注解是方法级别的,每个测试方法执行时都会执行被@Rule注解的成员变量的方法(类似于@Before)。
  • @ClassRule注解是类级别的,测试类执行时仅会执行一次被@ClassRule注解的静态变量的方法(类似于@BeforeClass)。

JUnit Rule和@Before注解的区别

@Before注解的方法只能作用于当前测试类及其子类,而实现了TestRule的类可以被用于多个测试类,因此JUnit Rule可以降低代码重复度并且更灵活。
JUnit Rule可以实现@Before, @BeforeClass, @After, @AfterClass的所有功能,并且会更强大:

  1. 多个不同的rule对象用于同一个测试用例时,测试人员可以使用RuleChain来设定这些rule的执行先后顺序。
  2. JUnit Rule提供了多个实用的内置Rule:
    • ExpectedException:支持在测试中指定期望抛出的异常类型,类似于@Test(expected = xxxException.class)
    • ExternalResource:支持提前建立好资源并且会在测试结束后将其销毁,这对于使用Socket、数据库链接等资源的测试来说很有用。
    • TemporaryFolder:支持创建文件与目录并且在测试运行结束后将其删除,这对于使用文件系统且独立运行的测试来说很有用。
    • TestName:支持在测试中获取当前测试方法的名称。
    • TestWatcher:提供五个触发点:测试开始、测试完成、测试成功、测试跳过、测试失败,允许我们在每个触发点执行自定义的逻辑。
    • Timeout:支持为测试类中的所有测试方法设置相同的超时时间,类似于@Test(timeout = 100)

内置Rule使用示例:

  • TemporaryFolder示例:

 

// 使用系统临时目录,可在构造方法上加入路径参数来指定临时目录
@Rule  
public TemporaryFolder tempFolder = new TemporaryFolder();  
  
@Test  
public void testTempFolderRule() throws IOException {  
    // 在系统的临时目录下创建文件或者目录,当测试方法执行完毕自动删除  
    tempFolder.newFile("test.txt");  
    tempFolder.newFolder("test");  
} 
  • Timeout示例:

 

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;

public class TimeoutTest {
    @Rule
    public Timeout timeout = new Timeout(1000);  

    // 测试失败
    @Test
    public void test1() throws Exception {
        Thread.sleep(1001);
    }

    // 测试成功
    @Test
    public void test2() throws Exception {
        Thread.sleep(999);
    }
}

自定义Rule

自定义的Rule只需实现TestRule接口,并实现其中apply()方法即可,该方法返回一个Statement对象。
下面展示一个用于循环调用测试方法的Rule,该类中的base.evaluate();用于继续运行测试方法。

 

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

public class LoopRule implements TestRule {
    private int loopCount;

    public LoopRule(int loopCount) {
        this.loopCount = loopCount;
    }

    @Override
    public Statement apply(Statement base, Description desc) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                for (int i = 1; i <= loopCount; i++) {
                    System.out.println("Loop " + i + " started");
                    base.evaluate();
                    System.out.println("Loop " + i + " finished\n----------------");
                }
            }
        };
    }
}

测试类:

 

import org.junit.Rule;
import org.junit.Test;

public class HelloWorldTest {
    @Rule
    public LoopRule loopRule = new LoopRule(2);

    @Test
    public void testSayHello() {
        System.out.println("helloWorld");
    }
}

测试输出结果:

 

Loop 1 started
helloWorld
Loop 1 finished
----------------
Loop 2 started
helloWorld
Loop 2 finished
----------------

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值