Sunday 1 July 2018

Junit: Working with text fixtures @Before, @After, @BeforeClass, @AfterClass

Text fixtures are used to eliminate duplicate code.

Let me explain with an example.
public class CollectionsTest {

 private List<String> list;
 
 @Test
 public void collection_emptyTest() {
  list = new ArrayList<> ();
  assertEquals(list.size(), 0);
  list = null;
 }
 
 @Test
 public void collection_elementTest() {
  list = new ArrayList<> ();
  list.add("Hello");
  assertEquals(list.size(), 1);
  list = null;
 }
 
}

As you observe above example, below statements are repeated in both the test cases.
a.   list = new ArrayList<> ();     // Initialization task
b.   list = null;  // Cleanup task

We can get rid of this duplicated code using text fixtures @Before, @After.


CollectionTest.java
package com.sample.test;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class CollectionsTest {

 private List<String> list;

 @Before
 public void setUp() {
  list = new ArrayList<>();
 }

 @Test
 public void collection_emptyTest() {
  assertEquals(list.size(), 0);
  list = null;
 }

 @Test
 public void collection_elementTest() {
  list.add("Hello");
  assertEquals(list.size(), 1);

 }

 @After
 public void cleanUp() {
  list = null;
 }

}

@Before annotation
If you annotate any method with @Before annotation, then then that method runs before the every test case ('org.junit.Test' method). In case of inheritance, The @Before methods of super classes will be run before those of the current class, unless they are overridden in the current class. It is mainly used for initializing activities.

@After annotation
If you annotate any method with @After annotation, then then that method runs after the every test case ('org.junit.Test' method). It is mainly used for cleanup activities. In case of inheritance, the @After annotated methods declared in super classes will run after those of the current class, unless they are overridden in the current class.

In the above example, tests might execute in below order. The ordering of the tests execution is not guaranteed. so collection_elementTest () might be executed before collection_emptyTest().

setUp()
collection_emptyTest()
cleanUp()
setUp()
collection_elementTest()
cleanUp()


Apart from @Before, @After annotations, junit provides @BeforeClass, @AfterClass annotations, these will get executed once for all the testcases. Sometimes some tests need to share the common setup like data base connections, log files etc., In these kind of cases, you can place the initialization code in @BeforeClass annotated method and cleanup code in @AfterClass method.

Example
@BeforeClass
public static void init() {
         System.out.println("I am in init");
}
        
@AfterClass
public static void destroy() {
         System.out.println("\nI am in destroy");
}

Find the below working application.

TestApplicaiton.java
package com.sample.test;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class TestApplicaiton {

 @BeforeClass
 public static void init() {
  System.out.println("I am in init");
 }

 @Before
 public void setUp() {
  System.out.println("\nI am in setUp method");
 }

 @Test
 public void testCase1() {
  System.out.println("I am in testCase1");
 }

 @Test
 public void testCase2() {
  System.out.println("I am in testCase2");
 }

 @After
 public void cleanUp() {
  System.out.println("I am in cleanUp");
 }

 @AfterClass
 public static void destroy() {
  System.out.println("\nI am in destroy");
 }

}


When you ran TestApplication.java, you can able to see below messages in console.

I am in init

I am in setUp method
I am in testCase1
I am in cleanUp

I am in setUp method
I am in testCase2
I am in cleanUp

I am in destroy






Previous                                                 Next                                                 Home

No comments:

Post a Comment