@Rule做什么?

时间:2015-07-22 22:37:16

标签: java junit rule

当我尝试为单元测试创​​建一个临时文件时,我遇到了提到“TemporaryFolder JUnit @Rule”的this answer和一个解释如何使用它的link。这是这样的:

@Rule
public TemporaryFolder testFolder = new TemporaryFolder();

然后testFolder.newFile("file.txt")

我的问题是@Rule注释是做什么的?

删除注释似乎并没有实际改变任何内容。

1 个答案:

答案 0 :(得分:6)

作为RuleTemporaryFolder状态的文档,它负责在各个​​类的每个测试方法之前创建临时目录,并在每个测试方法之后删除此临时文件夹(及其内容)

您可以通过实施TestRuleMethodRule或从ExternalResource等任何实施类扩展来轻松编写自己的规则。

使用@Before@After带注释的初始化和清理方法可以保证相同的逻辑。但是,您需要将逻辑添加到测试类中。如果您需要多个测试类中的逻辑,则需要使用继承,编写一些任意的实用程序类或将行为外部化。规则完全遵循后者,允许您重新使用这种初始化或清理逻辑,并进一步减少代码并删除不需要的代码,以便将重点放在实际测试而不是某些目录或服务器的配置上。 / p> 例如,

This project声明了两种服务器(Jetty或Tomcat),您只需要使用@Rule进行注释,以便使用服务器进行集成或端到端测试。

如果您只想为所有测试方法初始化一次规则,只需将@Rule替换为@ClassRule,并将规则初始化为public static。这将仅初始化类规则一次,并将为每个测试方法重用。

@ClassRule
public static JettyServerRule server = new JettyServerRule(new EmbeddedJetty());

@Test
public void myUnitTest() {
    RestTemplate restTemplate = new RestTemplate();
    String url = String.format("http://localhost:%s", server.getPort());

    String response = restTemplate.getForObject(url, String.class);

    assertEquals("Hello World", response);
}

上面的示例只会初始化Jetty服务器一次,并且测试类的每个测试方法都可以重用此服务器,而不是为每个方法启动和拆除新服务器。

多个规则甚至可以与RuleChain结合使用:

@Rule
public RuleChain chain= RuleChain.outerRule(new LoggingRule("outer rule")
                                 .around(new LoggingRule("middle rule")
                                 .around(new LoggingRule("inner rule");

在我们的一个集成测试中,它同时向我们通过Jetty上的Restlet部署的JAX-RS服务发送了几个请求,我们有以下规则定义:

public static SpringContextRule springContextRule;
public static RestletServerRule restletServer;

static {
    springContextRule = new SpringContextRule(JaxRsRestletTestSpringConfig.class);
    restletServer = new RestletServerRule(springContextRule.getSpringContext());
}

@ClassRule
public static RuleChain ruleChain = RuleChain.outerRule(restletServer).around(springContextRule);

// Tempus Fugit rules
@Rule
public ConcurrentRule concurrently = new ConcurrentRule();

@Rule
public RepeatingRule repeatedly = new RepeatingRule();

在启动Restlet / Jetty服务器以启用Spring bean注入之前初始化spring注释上下文。此外,Tempus Fugit规则用于同时执行测试方法几次,以便更早地发现竞争条件和并发相关问题。