Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.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是否在每次调用测试方法时重新初始化类?_Java_Unit Testing_Junit_Junit4_Junit3 - Fatal编程技术网

Java Junit是否在每次调用测试方法时重新初始化类?

Java Junit是否在每次调用测试方法时重新初始化类?,java,unit-testing,junit,junit4,junit3,Java,Unit Testing,Junit,Junit4,Junit3,当我运行以下代码时,两个测试用例都实现了: import static junit.framework.Assert.assertEquals; import org.junit.Test; public class MyTest{ private int count; @Before public void before(){ count=1; } @Test public void test1(){ co

当我运行以下代码时,两个测试用例都实现了:

import static junit.framework.Assert.assertEquals;

import org.junit.Test;

public class MyTest{
    private int count;

    @Before
    public void before(){
        count=1;
    }

    @Test
    public void test1(){
        count++;
        assertEquals(2, count); 
    }

    @Test
    public void test2(){
        count++;
        assertEquals(2, count); 
    }
}
预期行为

  • 测试1-成功
  • test2-失败(正如预期的那样,计数将变为3)
  • 实际行为

  • 测试1-成功
  • 测试2-成功
  • 为什么junit在每次调用测试方法时都要重新初始化类/变量。
    这是junit中的一个bug,或者是故意提供的。

    这是因为测试隔离


    任何测试都不应该依赖于其他测试。

    不要在构造函数中初始化测试类状态,除非它是不可变的

    JUnit不会为每个
    @test
    实例化您的测试类。事实上,它只在每个方法之前运行标记为
    @Before
    的方法,并在类中的所有测试之前运行一次
    @BeforeClass
    方法

    但是,不能保证测试运行程序实际上只使用测试类的一个实例来运行测试。它可以自由使用很多——考虑并行运行一组测试,甚至在不同的机器上。

    虽然通常有JUnit runner设置来控制这一点,但最好只遵循JUnit设计并在一个只在之前标记为@的方法中初始化测试状态。

    每个测试方法的新实例MyTest 对于每个测试方法,将创建一个新的
    MyTest
    实例,这是Junit的行为

    因此,对于这两种方法,变量
    count
    的值都是
    1
    ,因此对于这两种测试方法
    count++
    的值都是
    2
    ,因此测试用例通过

    public class MyTest{
       public MyTest(){
          // called n times
          System.out.println("Constructor called for MyTest");
       }
    
       @Before //called n times
       public void setUp(){
          System.out.println("Before called for MyTest");
       }
    
       //n test methods
    }
    
    如果使用2种测试方法执行上述代码:

    输出将是:

    Constructor called for MyTest
    Before called for MyTest
    //test execution
    Constructor called for MyTest
    Before called for MyTest
    

    查看以下文件:

    默认运行程序实现保证 测试用例类将在运行 测试,并且转轮将不保留对测试用例的引用 实例,通常使它们可用于垃圾收集


    单元测试应该是独立的,否则它将变得不可维护。请注意,执行方法的顺序不受保证(除非您使用注释
    @FixMethodOrder
    )。

    如果您希望在所有测试中使用测试类的成员变量,而不将其重新初始化为null,则将其设为静态。

    回答JUnit 5 在JUnit5中,使用注释控制此行为。注释可以采用以下两个生命周期限定符之一作为值:

    • @TestInstance(Lifecycle.PER_CLASS)
      :对于类中的所有方法,测试类将初始化一次
    • @TestInstance(Lifecycle.PER_METHOD)
      :测试类将在每个测试方法之前重新初始化(其他答案中描述的行为)
    如果测试类没有用
    @TestInstance
    注释,则默认行为是
    每_方法


    有关更多详细信息,请参阅JUnit5用户指南。

    在本例中,它们不依赖于一个another@SeanOwen是的,但是如果junit对每个测试方法都重用MyTest实例,那么测试可能会相互影响。这就是junit为每个测试方法创建MyTest的新实例的原因。如果测试可能相互影响,那么很难找到失败的原因,不是吗?我完全同意让测试独立。我原以为问题更多的是关于如何正确实现它,但我现在不太确定,所以这实际上可能是重点。我认为这更多的是评论。我想,在Stackoverflow中没有足够的声誉来添加评论:)(但显然足以添加答案!惊喜)