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

Pra*_*eek 16 java junit unit-testing 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(){
        count++;
        assertEquals(2, count); 
    }

    @Test
    public void test2(){
        count++;
        assertEquals(2, count); 
    }
}
Run Code Online (Sandbox Code Playgroud)

预期的行为

  1. test1 - 成功
  2. test2 - 失败(正如预期的那样,计数将变为3)

实际行为

  1. test1 - 成功
  2. test2 - 成功

为什么junit适用reinitializing class/variable于每个测试方法调用.这是junit中的错误或故意提供.

Ren*_*ink 20

这是因为测试隔离.

没有测试应该依赖于另一个.

  • @Sean Owen是但是如果junit会为每个测试方法重用MyTest实例,那么测试可能会相互影响.这就是为什么junit为每个测试方法创建一个新的MyTest实例.如果测试可能会相互影响,那么很难找到失败的原因,不是吗? (2认同)

Nar*_*hai 13

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
}
Run Code Online (Sandbox Code Playgroud)

如果您使用2种测试方法执行上述代码:

输出将是:

Constructor called for MyTest
Before called for MyTest
//test execution
Constructor called for MyTest
Before called for MyTest
Run Code Online (Sandbox Code Playgroud)


Lau*_*ntG 6

看看以下文档org.junit.runner.Runner:

默认的运行程序实现保证在运行测试之前立即构造测试用例类的实例,并且运行器将不保留对测试用例实例的引用,通常使它们可用于垃圾回收.

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


小智 6

JUnit 5 的答案

在 JUnit5 中,此行为是使用@TestInstance注释来控制的。该注释可以采用两个生命周期限定符之一作为值:

  • @TestInstance(Lifecycle.PER_CLASS):测试类将为类中的所有方法初始化一次。
  • @TestInstance(Lifecycle.PER_METHOD):测试类将在每个测试方法之前重新初始化(其他答案中描述的行为)。

如果测试类未使用 进行注释@TestInstance,则默认行为是PER_METHOD

有关更多详细信息,请参阅《JUnit5 用户指南》中的测试实例生命周期。