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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14010222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 14:43:18  来源:igfitidea点击:

JUnit: new instance before invoking each @Test method. What are the benefits?

javaunit-testingtestingjunitinstance

提问by user471011

Currently, I am reading "JUnit in action" book. In this book I found text below:

目前,我正在阅读“JUnit in action”一书。在这本书中,我发现了以下文字:

JUnit creates a new instance of the test class before invoking each @Test method. This helps provide independence between test methods and avoids unintentional side effects in the test code. Because each test method runs on a new test class instance, we can't reuse instance variable values across test methods.

JUnit 在调用每个 @Test 方法之前创建测试类的新实例。这有助于提供测试方法之间的独立性并避免测试代码中的意外副作用。因为每个测试方法都在一个新的测试类实例上运行,所以我们不能跨测试方法重用实例变量值。

Now I do not see much point in this approach:

现在我认为这种方法没有多大意义:

For example:

例如:

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);
    }
}

For test class CalculatorTest there are no any benefits.

对于测试类 CalculatorTest 没有任何好处。

Ok, lets go pay attention on another example:

好的,让我们注意另一个例子:

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);
    }
}

For test class OneTest I found a way to use the same variable count for the many test methods...

对于测试类 OneTest,我找到了一种对许多测试方法使用相同变量计数的方法......

so, How to see the real benefits of the approach described in the book?

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

回答by Vikdor

How to see the real benefits of the approach described in the book?

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

The purpose of separate instance is not for any benefit but to maintain the contract that each test should be independently executed without any effect of the execution of a previous test. There is just no other way to ensure this contract other than using a different instance for each test.

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

For example, the Spring transaction management makes sure to rollback all changes made to the database by a test, by default, to maintain the same contract.

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

So, using static variables in a test is generally discouraged as it will defeat the whole purpose of one-instance-per-test to have a clean slate for each test.

因此,通常不鼓励在测试中使用静态变量,因为它会破坏每个测试一个实例的整个目的,即为每个测试提供一个干净的石板。

回答by Cedric Beust

Keeping the state clean between test methods is useful for unit tests but gets in the way for functional tests, where having dependencies between tests is often necessary (for example, when you are testing web pages using Selenium, it's useful to not bother running tests of a certain page if the tests for the login page failed).

保持测试方法之间的状态干净对于单元测试很有用,但会妨碍功能测试,其中测试之间的依赖关系通常是必要的(例如,当您使用 Selenium 测试网页时,不打扰运行测试很有用如果登录页面的测试失败,则访问某个页面)。

This was one of the main reasons why I created TestNG, which doesn't instantiate a new class between each method, therefore giving you the choice instead of imposing this decision on you.

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

TestNG also supports dependencies of tests, multithread testing, has the notion of groups ("only run the servlet tests") and many more features.

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

回答by Don Roby

If you're testing a mutable class, there's great value in having your tested object in a known state at the beginning of each test method, so that the order of test execution does not matter. The easiest way to accomplish that is to create a new instance of that class for each test, and to avoid static fields.

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

In your calculator example, it appears that your Calculatorclass is immutable and the results of method calls depend only on the parameters. So the risk of one test influencing another is just not there.

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

I don't quite see the point of your second example. You've written methods annotated as @Testthat use a shared static field, but your methods have no assertions, and are not really testing anything.

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

If you want to do use static fields or indeed to hold onto and reuse a single instance of the class under test, it's certainly possible to to so, but to make your tests work and stay independent of each other will tend to require more care.

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