Java 如何在任何类中的任何测试之前和之后运行一组代码?
这里是我的测试代码:Java 如何在任何类中的任何测试之前和之后运行一组代码?,java,unit-testing,junit,initialization,Java,Unit Testing,Junit,Initialization,这里是我的测试代码: public class Test1 { @BeforeClass public void setUp() { EmbeddedTomcat.start(); } // test methods... @AfterClass public void tearDown() { EmbeddedTomcat.stop(); } } public class Test2 {
public class Test1 {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
// test methods...
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
public class Test2 {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
// test methods...
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
// ...
如您所见,我在每个测试类中复制了对嵌入式tomcat的启动和停止调用。如何使用JUnit避免这种重复
要求:
-必须为所有测试类调用一次启动和停止调用
JUnit4.11如果您的项目可能,您可以创建一个
TestParent
类,该类定义这些@BeforeClass
和@AfterClass
方法,并使您的Test1
和Test2
类从中扩展
public class TestParent {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
public class Test1 extends TestParent {
//...
}
public class Test2 extends TestParent {
//...
}
如果项目可能,您可以创建一个
TestParent
类,该类定义这些@BeforeClass
和@AfterClass
方法,并使您的Test1
和Test2
类从中扩展
public class TestParent {
@BeforeClass
public void setUp() {
EmbeddedTomcat.start();
}
@AfterClass
public void tearDown() {
EmbeddedTomcat.stop();
}
}
public class Test1 extends TestParent {
//...
}
public class Test2 extends TestParent {
//...
}
除了生成运行
@BeforeClass
和@AfterClass
的父类之外。您可以创建一个JUnit。您可以创建规则子类,该子类具有用于在执行(类或测试)之前和之后添加行为的重写方法
然后在测试中使用@ClassRule
,它在BeforeClass
和AfterClass
期间运行服务器的before()
和AfterClass
方法
public class Test1 {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
//tests as normal, no more @BeforeClass or @AfterClass
}
public class Test2 {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
//tests as normal, no more @BeforeClass or @AfterClass
}
此解决方案可能比使用父类更好,因为您可以在任何测试中使用此规则,而无需更改父类
编辑
只运行一次start()和stop()
现在还不清楚您的意思是否是每个测试类运行一次启动和停止(就像您最初使用@BeforeClass和@AfterClass的代码一样)
或者,如果希望在所有测试类中的所有测试上只运行一次start和stop,则可以运行所有测试类
如果你想做后者,@ClassRules在这里也很有用。只需创建一个包含要使用的测试类的测试套件,然后将ClassRule仅放在套件类中
@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
}
这将在AllTests套件启动时启动tomcat,然后在测试套件中的所有测试都已运行时停止tomcat。除了生成运行
@BeforeClass
和@AfterClass
的父类之外。您可以创建一个JUnit。您可以创建规则子类,该子类具有用于在执行(类或测试)之前和之后添加行为的重写方法
然后在测试中使用@ClassRule
,它在BeforeClass
和AfterClass
期间运行服务器的before()
和AfterClass
方法
public class Test1 {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
//tests as normal, no more @BeforeClass or @AfterClass
}
public class Test2 {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
//tests as normal, no more @BeforeClass or @AfterClass
}
此解决方案可能比使用父类更好,因为您可以在任何测试中使用此规则,而无需更改父类
编辑
只运行一次start()和stop()
现在还不清楚您的意思是否是每个测试类运行一次启动和停止(就像您最初使用@BeforeClass和@AfterClass的代码一样)
或者,如果希望在所有测试类中的所有测试上只运行一次start和stop,则可以运行所有测试类
如果你想做后者,@ClassRules在这里也很有用。只需创建一个包含要使用的测试类的测试套件,然后将ClassRule仅放在套件类中
@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
@ClassRule
public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
}
这将在AllTests套件启动时启动tomcat,然后在测试套件中的所有测试都已运行时停止tomcat。@ErrorAnswer OP使用在所有测试执行之前和之后执行的
@BeforeClass
和@AfterClass
,不是每次测试执行。@ErrorAnswer OP使用的是在所有测试执行之前和之后执行的@BeforeClass
和@AfterClass
,而不是每次测试执行。EmbeddedTomcatServer是什么?(枚举,类…@Stephan这是一个类,对不起,我修复了上面的代码,谢谢!现在出现了一个错误:“注释@Rule不允许用于此位置”从EmbeddedTomcatServer类中删除@Rule
(如果该类位于其自己的文件中,则删除结尾分号)。看起来规则API随着时间的推移而改变,因此您不再需要@rule。但还是要测试@ClassRuleclasses@Stephan还添加了仅在一次运行启动和停止的答案EmbeddedTomcatServer是什么?(枚举,类…@Stephan这是一个类,对不起,我修复了上面的代码,谢谢!现在出现了一个错误:“注释@Rule不允许用于此位置”从EmbeddedTomcatServer类中删除@Rule
(如果该类位于其自己的文件中,则删除结尾分号)。看起来规则API随着时间的推移而改变,因此您不再需要@rule。但还是要测试@ClassRuleclasses@Stephan还添加了仅在我刚刚添加了一个新要求时才运行启动和停止的答案:setUp
和tearDown
必须调用一次。我刚刚添加了一个新要求:setUp
和tearDown
必须调用一次。