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);
}
}
预期行为
这是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中没有足够的声誉来添加评论:)(但显然足以添加答案!惊喜)