Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最佳实践:在setUp()或声明中初始化JUnit类字段?_Java_Junit - Fatal编程技术网

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

Java 最佳实践:在setUp()或声明中初始化JUnit类字段?,java,junit,Java,Junit,我应该像这样在声明中初始化类字段吗 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 } } public cla

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

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
    }
}
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()中

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
    }
}
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()中初始化空集合的示例,因此我认为这一定是有原因的。

我更喜欢可读性第一,这通常不使用setUp方法。当基本设置操作需要很长时间并且在每次测试中重复时,我会例外。
此时,我使用
@BeforeClass
注释(稍后优化)将该功能移动到设置方法中

使用
@BeforeClass
设置方法进行优化的示例:我使用dbunit进行一些数据库功能测试。安装方法负责将数据库置于已知状态(非常慢…30秒-2分钟,取决于数据量)。我在用
@BeforeClass
注释的setup方法中加载此数据,然后对同一组数据运行10-20个测试,而不是在每个测试中重新加载/初始化数据库


使用Junit 3.8(如您的示例所示扩展TestCase)需要编写比添加注释多一点的代码,但是“在类设置之前运行一次”仍然是可能的。

除了Alex B的答案之外

甚至需要使用setUp方法来实例化处于特定状态的资源。在构造函数中执行此操作不仅是时间问题,而且由于JUnit运行测试的方式,每个测试状态在运行一个测试状态后都会被擦除

JUnit首先为每个测试方法创建testClass的实例,并在创建每个实例后开始运行测试。在运行测试方法之前,将运行其设置方法,在此方法中可以准备一些状态

如果数据库状态是在构造函数中创建的,那么所有实例都会在运行每个测试之前,依次实例化数据库状态。从第二个测试开始,测试将以脏状态运行

JUnits生命周期:

  • 为每个测试方法创建不同的testclass实例
  • 对每个testclass实例重复:调用setup+调用testmethod
  • 使用两种测试方法在测试中进行一些日志记录,您可以得到:(数字是哈希代码)

    • 创建新实例:571823
    • 正在创建新实例:5947506
    • 设置:571823
    • 测试一:571823
    • 设置:5947506
    • 测试二:5947506

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


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

    在您的情况下(创建列表),实践中没有区别。但通常最好使用setUp(),因为这将有助于Junit正确报告异常。如果测试的构造函数/初始值设定项中发生异常,则表示测试失败。但是,如果在安装过程中发生异常,自然会将其视为设置测试时的一些问题,junit会适当地报告它。

    由于每个测试都是独立执行的,并且有一个新的对象实例,因此测试对象除了在
    setup()之间共享的状态外,没有任何内部状态的意义
    和一个单独的测试和
    拆卸()。这是使用
    setUp()
    方法很好的一个原因(除了其他人给出的原因)

    注意:JUnit测试对象保持静态是个坏主意!如果在测试中使用静态变量不是为了跟踪或诊断,那么JUnit的部分目的就是无效的,即测试可以(可能)以任何顺序运行,每个测试都以全新的干净状态运行

    使用
    setUp()
    的优点是,您不必在每个测试方法中剪切和粘贴初始化代码,并且在构造函数中也不需要测试设置代码。在你的情况下,没有什么不同。只要创建一个空列表就可以安全地完成,正如您所显示的那样,或者在构造函数中,因为这是一个微不足道的初始化。但是,正如您和其他人所指出的,任何可能引发
    异常的操作都应该在
    setUp()
    中完成,因此如果失败,您将获得诊断堆栈转储


    在您的情况下,如果您只是创建一个空列表,我将按照您建议的方式执行:在声明点分配新列表。特别是因为这样,如果这对您的测试类有意义,您可以选择将其标记为
    final

    如果您特别想了解JUnit FAQ中的示例,例如,我认为这里展示的最佳实践是,应该在您的设置方法中实例化被测试的类(或在试验方法中)

    当JUnit示例在setUp方法中创建ArrayList时,它们都会继续测试该ArrayList的行为,例如testIndexOutOfBoundEx