-1

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

4

2 回答 2

2

如果设置和拆卸不同,您实际上是将两个不同的测试夹具塞进一个文件中。明智的答案是将它们放在单独的文件中并使用普通注释。如果它们有任何共同点,请将其分离到一个共同的抽象类中。

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

于 2013-08-07T20:43:16.243 回答
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
}

这是我的原始答案:

您可以尝试使用@BeforeClassand@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()在出现错误时也会调用它。

于 2013-08-07T20:33:41.537 回答