在tearDown(@After)方法上断言是错误的吗?

时间:2010-09-14 09:18:45

标签: java unit-testing junit

我甚至有多个测试用例,如果逻辑不同,输出必须在所有测试用例上相等。所以我在考虑如何概括它们并仅将Assert方法放置一次。

有没有比这更好的方法:

static public class Tests() {

    private static String expected = null;
    private String actual = null;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        expected = new String("My Desired Output");
    }

    @Before
    public void setUp() {
        actual = new String();
    }

    @Test
    public void test1() throws Exception {
        actual = ...
    }

    @Test
    public void test2() throws Exception {
        actual = ...
    }

    @After
    public void tearDown() throws Exception {
        assertThat(actual, is(equalTo(expected)));
    }

    @AfterClass
    public static void tearDownAfterClass() {
    }
}

跑步方法:

@Test
public void runTests() {
    Result result = JUnitCore.runClasses(Tests.class);
    assertThat(result.getRunCount(), is(2));
    assertThat(result.getFailureCount(), is(0));
}

3 个答案:

答案 0 :(得分:7)

是的,在tearDown方法中断言是个坏主意。根据JUnit文档,此方法存在于

  

拆除灯具,例如,关闭网络连接。执行测试后调用此方法。

我认为在测试类中存储您的预期值和实际值通常是个坏主意。这些变量与测试有关,因此将它们存储在测试用例中并在测试用例中执行断言。例如:

public class FooTest {

    @Test
    public void testFoo() {
        Object expected = // ...
        Object actual = // ...

        assertThat(actual, is(equalsTo(expected)));
    }

}

另外,我在您的代码中看到所有测试都具有相同的预期值。改变测试可能是个好主意,因此返回的值总是不同的。一直只测试一个预期值,确保代码适用于此预期结果。尝试更多,可能非常不同,并尝试测试一些极端情况。

答案 1 :(得分:4)

如果你必须概括,那么你可以创建一个方法,如

private void testIt ( String actual ) {
    assertThat(actual, is(equalTo(expected)));
}

并从所有测试方法中调用它。

如果测试失败,那么哪个测试失败将更加明显。

答案 2 :(得分:0)

我对现有答案的解释是,为了清楚起见,您不应该使用 tearDown 进行断言:

  • 我同意 this answer 从显式调用的一般方法中断言 从每个方法中可以更清楚地说明哪个测试失败了。

  • 我同意 that answer 的观点,即拆解中的断言 违背了拆解基础设施的初衷。以这种方式使用 assert 会使我们代码的意图变得不那么清晰。

但我认为值得明确提及 that answer 中可能也隐含的内容,即可能会引起混淆,tearDown 中的断言实际上可能会破坏您的测试逻辑。这在此 related Python answer 中得到了更清楚的证明:

<块引用>

在你的拆卸中断言某些东西意味着你需要小心 所有的清理工作都在实际断言之前完成 如果断言语句失败,则可能不会调用清理代码并且 加注。