JUnit单元测试6—@Rule注解

2019-09-26  本文已影响0人  莫问君心

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

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使用示例:

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

上一篇:JUnit单元测试5—PowerMock
下一篇:JUnit单元测试7—系统退出状态码

上一篇 下一篇

猜你喜欢

热点阅读