I have a JUnit test class that has two test methods:
我有一个JUnit测试类,它有两个测试方法:
@Test
public void test1() {
// Setup: Create foo1.m
// Exercise
// Tear Down: Delete foo1.m
}
@Test
public void test2() {
// Setup: Create foo2.m
// Exercise
// Tear Down: Delete foo2.m
}
For each method, I would like to make sure that, if the Exercise section fails for any reason, the Tear Down will still run. Note that the Setup and Tear Down code for both test methods are different, so I don't think I can use JUnit's @Before and @After annotations to do what I want.
对于每种方法,我想确保,如果练习部分由于任何原因失败,则撕裂仍然会运行。请注意,两种测试方法的Setup和Tear Down代码都不同,所以我认为我不能使用JUnit的@Before和@After注释来做我想要的。
I could put TRY-CATCH blocks into each test method:
我可以将TRY-CATCH块放入每个测试方法中:
@Test
public void test2() {
// Setup: Create foo2.m
try {
// Exercise
} finally {
// Tear Down: Delete foo2.m
}
}
but that seems ugly. Is there a way to make sure the test-method-specific tear down code in each test method is executed, without using a TRY-CATCH block?
但这看起来很难看。有没有办法确保在不使用TRY-CATCH块的情况下执行每个测试方法中特定于测试方法的拆卸代码?
2 个解决方案
#1
1
Update:
I found a better solution, so I include here, the original answer can be found below. I think JUnit 4 rules can be used here:
我找到了一个更好的解决方案,所以我在这里包含,原始答案可以在下面找到。我认为JUnit 4规则可以在这里使用:
class PrepareFile implements org.junit.rules.TestRule {
@Retention(RetentionPolicy.RUNTIME)
public @interface FileName {
String value() default "";
}
@Override
public Statement apply(final Statement statement, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
String fileName = description.getAnnotation(FileName.class).value();
File file = new File(fileName);
try {
file.createNewFile();
statement.evaluate();
} finally {
file.delete();
}
}
};
}
}
Using it in the test:
在测试中使用它:
@Rule
public PrepareFile prepareFile = new PrepareFile();
@Test
@PrepareFile.FileName("foo1.m")
public void test1() {
// Exercise
}
@Test
@PrepareFile.FileName("foo2.m")
public void test2() {
// Exercise
}
Here comes my original answer:
我的原始答案是:
You may try to use the @BeforeClass
and @AfterClass
annotations.
您可以尝试使用@BeforeClass和@AfterClass注释。
@BeforeClass
public static void setUp() {
// Setup1: Create foo1.m
// Setup2: Create foo2.m
}
@AfterClass
public static void tearDown() {
// Tear Down1: Delete foo1.m
// Tear Down2: Delete foo2.m
}
@Test
public void test1() {
// Exercise
}
@Test
public void test2() {
// Exercise
}
This way you can setup and tear down all test cases once and the framework ensures that teadDown()
is called in case of errors as well.
这样,您可以设置和拆除所有测试用例一次,框架确保在出现错误时调用teadDown()。
#2
2
If the setup and teardown are different, you are essentially cramming two different test fixtures into a single file. The sensible answer is to put them in separate files and use the normal annotations. If they have anything in common separate that out into a common abstract class.
如果设置和拆卸不同,您基本上将两个不同的测试夹具塞进一个文件中。明智的答案是将它们放在单独的文件中并使用正常的注释。如果他们有任何共同点,那就分成一个共同的抽象类。
Adding multiple setups in the same file can easily result in a situation where it's not clear which instance members are used in which tests, so that maintaining the tests becomes a lot harder than it needs to be.
在同一个文件中添加多个设置很容易导致一种情况,即不清楚哪些实例成员在哪些测试中使用,因此维护测试变得比它需要的要困难得多。
#1
1
Update:
I found a better solution, so I include here, the original answer can be found below. I think JUnit 4 rules can be used here:
我找到了一个更好的解决方案,所以我在这里包含,原始答案可以在下面找到。我认为JUnit 4规则可以在这里使用:
class PrepareFile implements org.junit.rules.TestRule {
@Retention(RetentionPolicy.RUNTIME)
public @interface FileName {
String value() default "";
}
@Override
public Statement apply(final Statement statement, final Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
String fileName = description.getAnnotation(FileName.class).value();
File file = new File(fileName);
try {
file.createNewFile();
statement.evaluate();
} finally {
file.delete();
}
}
};
}
}
Using it in the test:
在测试中使用它:
@Rule
public PrepareFile prepareFile = new PrepareFile();
@Test
@PrepareFile.FileName("foo1.m")
public void test1() {
// Exercise
}
@Test
@PrepareFile.FileName("foo2.m")
public void test2() {
// Exercise
}
Here comes my original answer:
我的原始答案是:
You may try to use the @BeforeClass
and @AfterClass
annotations.
您可以尝试使用@BeforeClass和@AfterClass注释。
@BeforeClass
public static void setUp() {
// Setup1: Create foo1.m
// Setup2: Create foo2.m
}
@AfterClass
public static void tearDown() {
// Tear Down1: Delete foo1.m
// Tear Down2: Delete foo2.m
}
@Test
public void test1() {
// Exercise
}
@Test
public void test2() {
// Exercise
}
This way you can setup and tear down all test cases once and the framework ensures that teadDown()
is called in case of errors as well.
这样,您可以设置和拆除所有测试用例一次,框架确保在出现错误时调用teadDown()。
#2
2
If the setup and teardown are different, you are essentially cramming two different test fixtures into a single file. The sensible answer is to put them in separate files and use the normal annotations. If they have anything in common separate that out into a common abstract class.
如果设置和拆卸不同,您基本上将两个不同的测试夹具塞进一个文件中。明智的答案是将它们放在单独的文件中并使用正常的注释。如果他们有任何共同点,那就分成一个共同的抽象类。
Adding multiple setups in the same file can easily result in a situation where it's not clear which instance members are used in which tests, so that maintaining the tests becomes a lot harder than it needs to be.
在同一个文件中添加多个设置很容易导致一种情况,即不清楚哪些实例成员在哪些测试中使用,因此维护测试变得比它需要的要困难得多。