在 (Junit) 单元测试中创建"new"对象 在 @Before 设置方法 VS. "clearing"还是"emptying"类/全局级别变量?最佳实践?



我想知道在单元测试中,是否最好将Set、Maps、LinkedLists或Arrays等对象实例化为类的字段,然后在每个@Test之前运行的@Before方法中清除它们?还是简单地实例化@Before方法中的对象,但将它们声明为类的字段更好?

#1例如,清除/清空数据结构并重新使用

public class MyUnitTestExample1 {

// Declare variable as field of class/member variable
private Set<String> set = new HashSet<>();
private Map<String, Integer> map = new HashMap<>();
@Before
public void setUp() {
// Data structure should be cleared before each test, but only instantiated 1 time?
set.clear();
map.clear();
}

#2例如,在每次测试中实例化新对象,但声明为类的字段,以便类中的每个@test都可以访问它

public class MyUnitTestExample2 {
// Declare variable as field of class/member variable
private Set<String> set;
private Map<String, Integer> map;
@Before
public void setUp() {
// Instantiate here
set = new HashSet<>();
map = new HashMap<>();
}

一个比另一个好吗?效率更高?更快?我认为清除数据结构的内容并实例化1次(或者我认为是这样做的(是否更快?

清除@BeforeEach中的实例变量毫无意义——JUnit为每个测试实例化测试类的一个新实例。

public class MyUnitTestExample1 {
private Set<String> set = new HashSet<>();
@Test
void test1() {
System.out.println(this);
System.out.println(System.identityHashCode(set));
}
@Test
void test2() {
System.out.println(this);
System.out.println(System.identityHashCode(set));
}
}

输出

com.sandbox.MyUnitTestExample1@3857f613
428566321
com.sandbox.MyUnitTestExample1@fa4c865
1004023029
  1. 我认为性能对这种情况并不重要。HashMap/Set的清除或新建以及通过垃圾收集清除旧对象都应该花费最少的时间。即使有数千个条目,填充地图/集合也需要比清除地图/集合更长的时间。

  2. 您应该更关心的是在单元测试类中使用变量;全局";用于该类的单元测试。我看不出有什么好处。我会在每个单元测试中使用一个新的集合/映射来将类内的测试分离为另一个。否则,根据测试的执行顺序,可能会产生副作用。我过去遇到过一些奇怪的场景,因为开发人员在Windows上运行,CI服务器在Linux上运行,所以测试产生了不同的结果。

最新更新