Home > OS >  Create "new" Objects in (Junit) Unit Tests in @Before setUp methods VS. "clearing&quo
Create "new" Objects in (Junit) Unit Tests in @Before setUp methods VS. "clearing&quo

Time:04-15

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:

  1. 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.

  2. 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
  • Related