最佳实践:在 setUp() 中或在声明时初始化 JUnit 类字段?

2022-08-31 08:11:20

我应该像这样在声明时初始化类字段吗?

public class SomeTest extends TestCase
{
    private final List list = new ArrayList();

    public void testPopulateList()
    {
        // Add stuff to the list
        // Assert the list contains what I expect
    }
}

还是在像这样的setUp()中?

public class SomeTest extends TestCase
{
    private List list;

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();
        this.list = new ArrayList();
    }

    public void testPopulateList()
    {
        // Add stuff to the list
        // Assert the list contains what I expect
    }
}

我倾向于使用第一种形式,因为它更简洁,并允许我使用最终字段。如果我不需要使用 setUp() 方法进行设置,我是否仍应使用它,为什么?

澄清:JUnit 将为每个测试方法实例化一次测试类。这意味着每个测试将创建一次,无论我在哪里声明它。这也意味着测试之间没有时间依赖关系。因此,使用setUp()似乎没有优势。但是,JUnit FAQ中有许多在setUp()中初始化空集合的示例,因此我认为一定有原因。list


答案 1

如果您特别想知道JUnit FAQ中的示例,例如基本测试模板,我认为那里展示的最佳实践是,所测试的类应该在您的setUp方法(或测试方法)中实例化。

当 JUnit 示例在 setUp 方法中创建一个 ArrayList 时,它们都会继续测试该 ArrayList 的行为,例如 testIndexOutOfBoundException、testEmptyCollection 等情况。那里的观点是有人写一门课并确保它正常工作。

在测试自己的类时,您可能也应该这样做:在 setUp 或测试方法中创建对象,以便在以后中断它时能够获得合理的输出。

另一方面,如果您在测试代码中使用Java集合类(或其他库类),那可能不是因为您想要测试它 - 它只是测试夹具的一部分。在这种情况下,您可以安全地假设它按预期工作,因此在声明中初始化它不会成为问题。

就其价值而言,我致力于一个相当大的,已有数年历史的TDD开发的代码库。我们习惯于在测试代码的声明中初始化事物,在我参与这个项目的一年半时间里,它从未引起过问题。因此,至少有一些轶事证据表明这是一件合理的事情。


答案 2

我开始挖掘自己,我发现使用.如果在执行 期间抛出任何异常,JUnit 将打印一个非常有用的堆栈跟踪。另一方面,如果在对象构造期间引发异常,错误消息只是说 JUnit 无法实例化测试用例,并且您看不到发生故障的行号,这可能是因为 JUnit 使用反射来实例化测试类。setUp()setUp()

这些都不适用于创建空集合的示例,因为这永远不会抛出,但这是该方法的一个优点。setUp()


推荐