JUnit4(四)高级之规则

JUnit4高级实践:规则详解与应用
本文详细介绍了JUnit4中的高级规则,包括TemporaryFolder、ExternalResource、ErrorCollector、Verifier、TestWatcher、TestName、Timeout和ExpectedException等基础规则,以及ClassRule注解和RuleChain的使用。通过示例展示了如何自定义规则,帮助读者更好地理解和运用JUnit进行测试。

一、基础规则

Rules【规则】允许在测试类中非常灵活的增加或重新定义每个测试方法的行为。测试人员可以重用或拓展下面提供的规则或编写自己的规则。

简单来说就是提供了测试用例在执行过程中通用功能的共享的能力,使我们不必重复编写一些功能类似的代码。

JUnit用于标注规则的注解包括@Rule@ClassRule,区别在于作用域不同:

  • @Rule的作用域是测试方法,每个测试方法执行时都会调用被注解的Rule
  • @ClassRule的作用域是测试类,在执行一个测试类的时候只会调用一次被注解的Rule

我们在使用规则的时候需要使用@Rule注解进行注释,被该注解注释的类实例需要是TestRule接口的实现,且作用于该类中的所有测试方法。

TestRule接口的实现

  1. TemporaryFolder:创建新文件,并在测试后删除
  2. ExternalResource:例如,启动和停止服务器
  3. ErrorCollector: 在一个测试方法中收集多个错误
  4. Verifier:如果对象状态不正确,则测试失败
  5. TestWatcher: 在方法执行期间添加事件的逻辑
  6. TestName: 记住在方法中使用的测试名称
  7. Timeout:使测试在设定的时间后失败
  8. ExpectedException:抛出异常的灵活断言

JUnit Rule主要包含三要素,运行测试的语句、选择需要运行哪些语句的规则以及@Rule标记。

在加入了@Rule后JUnit按如下流程运行测试:

  1. 创建默认语句运行测试
  2. 找出测试类中所有的标记了@Rule的public的成员规则
  3. 调用Rule中的apply()方法并告诉该方法所要运行的测试类和测试方法以及JUnit所收集到的语句。apply()方法决定怎么来运行测试,选择或者创建语句来运行测试并返回相应的语句传给JUnit。然后JUnit把语句传给下一个rule的apply方法,如此循环直到最后一条规则。
  4. 调用最后一条Rule返回的语句的evaluate()来运行测试

1.1 TemporaryFolder

TemporaryFolder规则允许创建文件或文件夹,在测试方法(无论是通过还是失败)执行完成时会被删除。默认情况下,如果资源无法被删除是不会抛出异常的:

public static class HasTempFolder {
   
   
  @Rule
  public final TemporaryFolder folder = new TemporaryFolder();

  @Test
  public void testUsingTempFolder() throws IOException {
    File createdFile = folder.newFile("myfile.txt");
    File createdFolder = folder.newFolder("subfolder");
    // ...
  }
}
  • TemporaryFolder#newFolder(String... folderNames) 会递归的创建一个临时文件夹。
  • TemporaryFolder#newFile() 创建一个随机名称的文件, 同样 #newFolder() 创建一个随机名称的文件夹

示例:

public class FileWriter {
   
   
    public void writeTo(String path, String content) throws IOException {
        Path target = Paths.get(path);
        if (Files.exists(target)) {
            throw new IOException("file already exists");
        }
        Files.copy(new ByteArrayInputStream(content.getBytes("UTF8")), target);
    }
}
//依赖于AssertJ
import static org.assertj.core.api.Assertions.assertThat;

public class FileWriterTest {
   
   
    private FileWriter fileWriter = new FileWriter();
    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder();

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void throwsErrorWhenTargetFileExists() throws IOException {
        // arrange
        File output = temporaryFolder.newFile("output.txt");

        thrown.expect(IOException.class);
        thrown.expectMessage("file already exists");

        // act
        fileWriter.writeTo(output.getPath(), "test");
    }

    @Test
    public void writesContentToFile() throws IOException {
        // arrange
        File output = temporaryFolder.newFolder("reports")
                .toPath()
                .resolve("output.txt")
                .toFile();

        // act
        fileWriter.writeTo(output.getPath(), "test");

        // assert
        assertThat(output)
                .hasContent("test")
                .hasExtension("txt")
                .hasParent(resolvePath("reports"));
    }

    private String resolvePath(String folder) {
        return temporaryFolder
                .getRoot().toPath()
                .resolve(folder)
                .toString();
    }
}

1.2 ExternalResource

ExternalResource是规则TemporaryFolder的基础类【是一个抽象类】,在测试之前建立一个外部资源(一个文件,套接字[socket],服务[server],数据库连接,等等),并且保证最后将其关闭。

public static class UsesExternalResource {
   
   
  Server myServer = new Server();

  @Rule
  public final ExternalResource resource = new ExternalResource() {
    @Override
    protected void before() throws Throwable {
      myServer.connect();
    };

    @Override
    protected void after() {
      myServer.disconnect();
    };
  };

  @Test
  public void testFoo() {
    new Client().run(myServer);
  }
}

1.3 ErrorCollector

ErrorCollector 规则允许在第一个问题发现之后继续运行(例如,收集下面不正确的行到一个表中,然后一次性报告所有错误。)

public static class UsesErrorCollectorTwice {
   
   
  @Rule
  public final ErrorCollector collector = new ErrorCollector();

  @Test
  public void example() {
    collector.addError(new<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值