在 @Before setUp 方法 VS 中的 (Junit) 单元测试中创建 "new" 个对象。 "clearing" or "emptying" Class/global 级变量?最佳实践?
Create "new" Objects in (Junit) Unit Tests in @Before setUp methods VS. "clearing" or "emptying" Class/global level variables? Best practices?
我想知道在单元测试中,将集合、映射、链表或数组等对象实例化为 Class 的 字段 是否更好,然后在每个 @Test 之前运行的 @Before 方法中清除它们?还是简单地在 @Before 方法中实例化对象但让它们声明为 class 的 field 更好?
#1 例如Clearing/Emptying 数据结构和复用
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 例如在每个测试中实例化新对象,但声明为 Class 的字段,以便 Class
中的每个 @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 次(或者我想它这样做)是 faster?
我认为这种情况下性能并不重要。 HashMap/Set 的清除或新创建以及通过垃圾收集清除旧对象都应该花费最少的时间。即使有数千个条目,填充 map/set 也比清除它需要更长的时间。
您应该更关心的是在单元测试 class 中使用变量,这些变量对于那个 class 的单元测试是“全局的”。我没有看到好处。我会在每个单元测试中使用一个新的 set/map 来将 class 中的测试分开。否则,根据测试的执行顺序,您可能会产生副作用。我过去遇到过奇怪的场景,测试产生了不同的结果,因为开发人员在 Windows 上 运行 而 CI 服务器在 Linux 上 运行。
清除 @BeforeEach
中的实例变量没有意义 - JUnit 为每个测试实例化一个新的测试实例 class。
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
我想知道在单元测试中,将集合、映射、链表或数组等对象实例化为 Class 的 字段 是否更好,然后在每个 @Test 之前运行的 @Before 方法中清除它们?还是简单地在 @Before 方法中实例化对象但让它们声明为 class 的 field 更好?
#1 例如Clearing/Emptying 数据结构和复用
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 例如在每个测试中实例化新对象,但声明为 Class 的字段,以便 Class
中的每个 @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 次(或者我想它这样做)是 faster?
我认为这种情况下性能并不重要。 HashMap/Set 的清除或新创建以及通过垃圾收集清除旧对象都应该花费最少的时间。即使有数千个条目,填充 map/set 也比清除它需要更长的时间。
您应该更关心的是在单元测试 class 中使用变量,这些变量对于那个 class 的单元测试是“全局的”。我没有看到好处。我会在每个单元测试中使用一个新的 set/map 来将 class 中的测试分开。否则,根据测试的执行顺序,您可能会产生副作用。我过去遇到过奇怪的场景,测试产生了不同的结果,因为开发人员在 Windows 上 运行 而 CI 服务器在 Linux 上 运行。
清除 @BeforeEach
中的实例变量没有意义 - JUnit 为每个测试实例化一个新的测试实例 class。
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