我想为大量的代码编写测试用例,我想知道JUnit @Rule注释功能的细节,以便我可以使用它来编写测试用例。请提供一些好的答案或链接,通过一个简单的例子详细描述其功能。


规则用于添加额外的功能,这些功能应用于测试类中的所有测试,但以一种更通用的方式。

例如,ExternalResource在测试方法之前和之后执行代码,而不必使用@Before和@After。使用ExternalResource而不是@Before和@After提供了更好的代码重用机会;相同的规则可以用于两个不同的测试类。

该设计基于:JUnit中的拦截器

有关更多信息,请参阅JUnit wiki: Rules。


Junit规则的工作原理是AOP(面向方面的编程)。它拦截测试方法,从而提供了在特定测试方法执行之前或之后做一些事情的机会。

以下面的代码为例:

public class JunitRuleTest {

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  @Test
  public void testRule() throws IOException {
    File newFolder = tempFolder.newFolder("Temp Folder");
    assertTrue(newFolder.exists());
  }
} 

每次执行上述测试方法时,都会创建一个临时文件夹,并在方法执行后删除该文件夹。这是一个由Junit提供的开箱即用规则的示例。

类似的行为也可以通过创建我们自己的规则来实现。Junit提供了TestRule接口,可以实现该接口来创建我们自己的Junit Rule。

这里有一个有用的链接供参考:

http://www.codeaffine.com/2012/09/24/junit-rules/


它的工作原理是:

JUnit将测试方法包装在Statement对象中,以便Statement和Execute()运行测试。然后,JUnit不是直接调用Statement . execute()来运行测试,而是将Statement传递给带有@Rule注释的TestRule。TestRule的"apply"函数在给定测试语句的情况下返回一个新的语句。新的Statement的Execute()方法可以调用test Statement的Execute方法(或者不调用,或者多次调用),并在之前和之后执行它想做的任何事情。

现在,JUnit有了一个新的Statement,它不仅可以运行测试,还可以在最终调用Execute之前再次将其传递给任何其他规则。


规则用于以通用的方式增强每个测试方法的行为。Junit规则拦截测试方法,并允许我们在测试方法开始执行之前和测试方法执行之后做一些事情。

例如,使用@Timeout规则,我们可以为所有测试设置超时。

public class TestApp {
    @Rule
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS);

    ......
    ......

 }

@TemporaryFolder规则用于创建临时文件夹、文件。每次执行测试方法时,都会创建一个临时文件夹,并在方法执行后删除它。

public class TempFolderTest {

 @Rule
 public TemporaryFolder tempFolder= new TemporaryFolder();

 @Test
 public void testTempFolder() throws IOException {
  File folder = tempFolder.newFolder("demos");
  File file = tempFolder.newFile("Hello.txt");

  assertEquals(folder.getName(), "demos");
  assertEquals(file.getName(), "Hello.txt");

 }


}

在这个链接中可以看到junit提供的一些内置规则的示例。