I was wondering if in a Unit Test, is it better to instantiate Objects like Sets, Maps, LinkedLists or Arrays as a field of the Class and then in the @Before method that runs before each @Test, to clear them? OR is it better to simply instantiate the Objects in the @Before method but have them declare as a field of a class?
#1 e.g. Clearing/Emptying data structure and re-using
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 e.g. Instantiating new Object every test but declaring as field of Class such that it is accessible by every @Test in the Class
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<>();
}
... is one better than the other? More efficient? Faster? I would assume clearing the contents of the data structures and instantiating 1 time (or so I suppose it does this) is faster?
CodePudding user response:
I dont think performance matters for such cases. The clearing or new creation of a HashMap/Set and clearing the old object via garbage collection should both take minimal time. Even with thousands of entries it takes much longer to fill the map/set than clearing it.
What you should be more concerned about is using variables in a unit test class that are "global" for the unit tests of that class. I do not see the benefit. I would use a new set/map in each unit test to separate the test inside the class for another. Otherwise you could have sideeffects depending on the order of execution of the test. I had weird scenarios in the past where tests produced different results because the developer was running on Windows and the CI server was running on Linux.
CodePudding user response:
Clearing instance variables in @BeforeEach
makes no sense - JUnit instantiates a new instance of your test class for each test.
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));
}
}
Output
com.sandbox.MyUnitTestExample1@3857f613
428566321
com.sandbox.MyUnitTestExample1@fa4c865
1004023029