如何确保我的JUnit测试方法的特定清理始终运行?

时间:2013-08-07 19:59:14

标签: java junit junit4

我有一个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
}

对于每种方法,我想确保如果练习部分由于任何原因失败,则撕裂仍将运行。请注意,两种测试方法的Setup和Tear Down代码都不同,所以我认为我不能使用JUnit的@Before和@After注释来做我想要的。

我可以将TRY-CATCH块放入每个测试方法中:

@Test
public void test2() {
    // Setup: Create foo2.m
    try {
        // Exercise
    } finally {
        // Tear Down: Delete foo2.m
    }
}

但这看起来很难看。有没有办法确保执行每个测试方法中特定于测试方法的拆卸代码,而不使用TRY-CATCH块?

2 个答案:

答案 0 :(得分:2)

如果设置和拆卸不同,您基本上将两个不同的测试夹具塞进一个文件中。明智的答案是将它们放在单独的文件中并使用正常的注释。如果他们有任何共同点,将它们分成一个共同的抽象类。

在同一个文件中添加多个设置很容易导致不清楚在哪些测试中使用哪些实例成员的情况,因此维护测试变得比它需要的要困难得多。

答案 1 :(得分:1)

<强>更新

我找到了一个更好的解决方案,所以我在这里包含,原始答案可以在下面找到。我认为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();
                }
            }
        };
    }
}

在测试中使用它:

@Rule
public PrepareFile prepareFile = new PrepareFile();

@Test
@PrepareFile.FileName("foo1.m")
public void test1() {
    // Exercise
}

@Test
@PrepareFile.FileName("foo2.m")
public void test2() {
    // Exercise
}

我的原始回答是:

您可以尝试使用@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
}

通过这种方式,您可以设置并拆除所有测试用例一次,框架可确保在出现错误时调用teadDown()