Junit @Rule如何工作?


195

我想编写大量代码的测试用例,我想了解JUnit @Rule批注功能的详细信息,以便可以将其用于编写测试用例。请提供一些好的答案或链接,通过一个简单的示例详细说明其功能。



我发现这篇文章解释@Rule做得相当好,尤其是检查出的最后一节“事件详细序列”
彼得Perháč

我认为它类似于注射的概念,对吗?

感谢您分享该链接。一件事还不清楚。DEFAULT Statement.evaluate()何时调用?它是在所有规则的validate()之前还是在所有规则之后调用?我猜都是这些。
MasterJoe2

@ testerjoe2,您可以选择完全忽略默认的Statement。您可以选择委托给它,也可以将其完全替换为您自己的其他一些声明。它不会被调用可以调用它或不调用它。那是第10点:“屏幕快照语​​句的validate()方法调用默认语句的validate()方法。”
PeterPerháč18年

Answers:


155

规则用于添加其他功能,这些功能适用于测试类中的所有测试,但以更通用的方式。

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

设计基于:JUnit中的拦截器

有关更多信息,请参见JUnit Wiki:规则


1
更正:“例如,ExternalResource在测试之前和之后执行代码。” 关于使用apply()来使ExternalResource在测试之间运行,存在一些问题。
derekm '16

62

Junit Rules根据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规则。

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


4
所以它被删除而无需编写任何代码来删除/清除对象?
Dror

查看github.com/junit-team/junit4/blob/master/src/main/java/org/…的来源,该文件夹是在before()回调方法中创建的,并在after()回调方法中删除的。 ..
Pierluigi Vernetto

1
对于可能不了解为什么会删除TemporaryFolder的人来说,这是因为它是Junit提供的一个TemporaryFolder,用作自动删除的临时文件夹-即拆卸步骤是TemporaryFolder类本身的一部分。
MindaugasBernatavičius19年

17

tl; dr的工作原理:JUnit将测试方法包装在Statement对象中,以便statement.Execute()运行测试。然后,JUnit无需直接调用statement.Execute()来运行测试,而是将带有@Rule批注的Statement传递给TestRule。给定与您的测试一起使用的TestRule的“ apply”函数将返回一个新的Statement。新Statement的Execute()方法可以调用测试Statement的execute方法(是否调用该方法,或多次调用它),以及在执行之前和之后执行的操作。现在,JUnit有了一个新的Statement,它不仅可以运行测试,而且还可以在最终调用Execute之前将其再次传递给任何其他规则。


2
语句有方法评估不执行。
Hemanth

0

规则用于以通用方式增强每种测试方法的行为。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");

 }


}

您可以在此链接上看到j​​unit提供的一些内置规则的示例。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.