当我尝试为单元测试创建一个临时文件时,我遇到了提到“TemporaryFolder JUnit @Rule”的this answer和一个解释如何使用它的link。这是这样的:
@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
然后testFolder.newFile("file.txt")
我的问题是@Rule注释是做什么的?
删除注释似乎并没有实际改变任何内容。
答案 0 :(得分:6)
作为Rule
和TemporaryFolder
状态的文档,它负责在各个类的每个测试方法之前创建临时目录,并在每个测试方法之后删除此临时文件夹(及其内容)
您可以通过实施TestRule
或MethodRule
或从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规则用于同时执行测试方法几次,以便更早地发现竞争条件和并发相关问题。