Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.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 JUnit:调用每个@Test方法之前的新实例。有什么好处?_Java_Unit Testing_Testing_Junit_Instance - Fatal编程技术网

Java JUnit:调用每个@Test方法之前的新实例。有什么好处?

Java JUnit:调用每个@Test方法之前的新实例。有什么好处?,java,unit-testing,testing,junit,instance,Java,Unit Testing,Testing,Junit,Instance,目前,我正在读《JUnit在行动》一书。在这本书中,我发现了以下内容: JUnit在调用每个类之前创建测试类的新实例 @试验方法。这有助于在测试方法和测试方法之间提供独立性 避免测试代码中的意外副作用。因为每次考试 方法在新的测试类实例上运行,我们不能重用该实例 测试方法中的可变值 现在我看不出这种方法有什么意义: 例如: public class CalculatorTest { @Test public void testAdd_1() { Calculato

目前,我正在读《JUnit在行动》一书。在这本书中,我发现了以下内容:

JUnit在调用每个类之前创建测试类的新实例 @试验方法。这有助于在测试方法和测试方法之间提供独立性 避免测试代码中的意外副作用。因为每次考试 方法在新的测试类实例上运行,我们不能重用该实例 测试方法中的可变值

现在我看不出这种方法有什么意义:

例如:

public class CalculatorTest {
    @Test
    public void testAdd_1() {
        Calculator calculator = new Calculator();
        double result = calculator.add(1, 1);
        assertEquals(2, result, 0);
    }

    @Test
    public void testAdd_2() {
        Calculator calculator = new Calculator();
        double result = calculator.add(2, 2);
        assertEquals(4, result, 0);
    }
}
对于测试类CalculatorTest,没有任何好处

好的,让我们开始关注另一个例子:

public class OneTest {

    static byte count;

    public OneTest() {
        count++;
    }

    @Test
    public void test1() {
        System.out.println(count);
    }

    @Test
    public void test2() {
        System.out.println(count);
    }
}
对于测试类OneTest,我找到了一种方法,可以对许多测试方法使用相同的变量计数

那么,如何看待书中描述的方法的真正好处呢

如何看到书中描述的方法的真正好处

单独实例的目的不是为了任何利益,而是为了维护合同,即每个测试应独立执行,而不受先前测试执行的任何影响。除了为每个测试使用不同的实例之外,没有其他方法可以确保这个契约

例如,Spring事务管理确保在默认情况下回滚测试对数据库所做的所有更改,以维护相同的契约


因此,通常不鼓励在测试中使用静态变量,因为它会破坏每个测试一个实例的全部目的,即每个测试都有一个干净的记录。

如果您正在测试一个可变类,那么在每个测试方法开始时让您的测试对象处于已知状态是非常有价值的,因此,测试执行的顺序并不重要。实现这一点的最简单方法是为每个测试创建该类的新实例,并避免使用静态字段

在计算器示例中,您的
calculator
类似乎是不可变的,并且方法调用的结果仅取决于参数。因此,一项测试影响另一项测试的风险并不存在

我不太明白你第二个例子的意思。您已经编写了注释为
@Test
的方法,它们使用一个共享的静态字段,但是您的方法没有断言,也没有真正测试任何东西


如果您确实想使用静态字段,或者确实想保留并重用被测类的单个实例,那么当然可以这样做,但是,要使您的测试能够工作并保持彼此独立,往往需要更多的注意。

保持测试方法之间的状态整洁对于单元测试很有用,但对于功能测试则会造成阻碍,因为在功能测试中,测试之间往往需要依赖关系(例如,当您使用Selenium测试web页面时,如果登录页面的测试失败,最好不要麻烦运行特定页面的测试)

这是我创建它的主要原因之一,它不会在每个方法之间实例化一个新类,因此给了您选择权,而不是将此决定强加给您


TestNG还支持测试的依赖关系,多线程测试,具有组的概念(“仅运行servlet测试”)还有更多的功能。

如果你说的是“count”字段,那么它是一个静态字段。它是类的属性,而不是特定的实例。这就是为什么你看到它的值发生了变化。@babasmith:你应该取消删除你的答案(也许可以通过显示一个带有非静态字段的示例来详细说明)。第一个示例:测试方法之间没有任何连接。在这种情况下,为执行每个测试方法创建新的测试类实例-没有意义。第二个示例:我们可以通过静态变量获得“无意的副作用”。))好处在哪里?好处是当您使用实例变量并在测试中修改它们时。目前,JUnit 5具有
@TestInstance(LifeCycle.PER_CLASS)
,这可能比切换到TestNG更容易。JUnit 5有一个奇怪的新命名约定,这使得它很难找到,下面是到Maven Central的链接: