04 - JUnit Core Objects

4. JUnit Core-Objects

                      4.1 Annotations

                      4.2 Assert statements

                      4.3 Test Case

                      4.4 Test Execution order

 

4.1 Annotations   

JUnit 4.x uses annotations to determine if a method is a test method and to configure the test run.

The most used annotations by JUnit are:

@Test

Identifies that a method is a test method.

@Test(expected=Exception.class)

Fails if the method does not throw the named exception.

@Test(timeout=100)

Fais, if the method takes longer than 100 milliseconds.

@Before

The method will be executed before each test. The method is used to prepare the test environment (read input data, initialize the class).

@After

The method will be executed after each test. The method can cleanup the test environment .

(delete temporary data, restore defaults)

@BeforeClass

Will execute the method before the start of all tests. This annotation can be used for intensive activities as connect to a database. Methods annotated with @BeforeClass need a static modifier to work with JUnit.

@AfterClass

Will execute the method once, after all tests have finished. This annotation can be used to clean-up activities, for example disconnect from a database. Method annotated with @AfterClass need a static modifier to work with JUnit.

@Ignore

This annotation will allow the tests to ignore the test method. This is useful when the code has been changed and the test case has not yet been adapted. Or if the execution time of this test is too long to be included.

Example:

import java.util.Calendar;
import java.util.Date;

public class Customer {
     private Date birthday;
     private String name;
   
     public Customer(String name, Date birthday ){
        this.birthday = birthday;
        this.name=name;
    }    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
     public int getAge() {
            Calendar cal = Calendar.getInstance();
            int actualYear = cal.get(Calendar.YEAR); 
            cal.setTime(birthday);
            int birthdayYear = cal.get(Calendar.YEAR);
            Date date = new Date();
            return birthday == null ? 0 : (actualYear - birthdayYear + 1);
        }    
}

import main.java.util.Customer;

import org.junit.*;

import java.util.Date;
import java.text.SimpleDateFormat;

public class CustomerTest  extends Assert {
    public static SimpleDateFormat dateformat;
    private Customer customer;

    @BeforeClass
    public static void BeforeClass() {
        dateformat = new SimpleDateFormat("yyyy-mm-dd");
        System.out.println("BeforeClass");
    } 
    @Before
    public void setUp() throws Exception {
        Date date = dateformat.parse("1977-03-17");
        customer = new Customer("Smith", date);
        System.out.println("setUp");
    } 
    @Test
    public void getName() {
        assertEquals(customer.getName(), "Smith");
        System.out.println("Test getName");
    } 
    @Test
    public void getAge() {
        assertEquals(customer.getAge(), 37);
        System.out.println("Test getAge");
    } 
    @After
    public void tearDown() throws Exception {
        customer = null;
        System.out.println("tearDown");
    } 
    @AfterClass
    public static void AfterClass() {
        df = null;
        System.out.println("AfterClass");
    }    
}

The output is:

BeforeClass

setUp

tearDown

setUp

Test getName

tearDown

AfterClass

reflecting the execution order of the methods.

4.2 Assert statements

In JUnit 4.x test classes do not inherit from TestCase and the Assert methods are not available to the test classes. In order to use Assert methods it can be use a static import of the Assert class

import static org.junit.Assert.*;

or the prefixed syntax:

Assert.assertEquals()

assertEquals ()

The assert methods takes two parameters. The first parameter is the value that we expect the method will return. The second parameter is what the actual value is.

For example:

            assertEquals(5,2+3);

The expected result of 2+3 will be 5 which is the first parameter and the second parameter is the result of what 2+5 is.

The assert method can have a third parameter that is a delta value for compare doubles and floats with fractional values.

assertEquals(6.0,2.0*3,0.0000001);

The available assert methods in the class org.junit.Assert are:

  • assertArrayEquals ()
  • assertEquals ()
  • assertTrue () / assertFalse ()
  • assertNull () / assertNotNull ()
  • assertSame () / assertNotSame ()
  • assertThat ()

assertArrayEquals ()

This method test if two arrays contains the same number of elements and if all the elements are equal to each other and if the elements are in the same order. The check is made with the equal() method. 

package main.java.util;

public class MyClass {
 
      private String[] myStringArray={"first1", "second", "third"};
 
      public MyClass(){  

      }

      public String[] getMyStringArray() {
        return myStringArray;
      }
      public void setMyStringArray(String[] myStringArray) {
        this.myStringArray = myStringArray;
      }    
} 

package test.java;

import static org.junit.Assert.*;
import main.java.util.MyClass;
import org.junit.Test;

public class MyClassTest {
    @Test
     public void testMyStringArray() {
            MyClass myClass = new MyClass();
 
            String[] expected = {"first", "second", "third"};
            String[] result =  myClass.getMyStringArray();
            assertArrayEquals(expected, result);
        }
}

After running the test the result is:

       assertTrue ()/assertFalse ()

package main.java.util;

public class MyClass {

     private Boolean myBoolean = false;    
     public MyClass(){

     }
    public Boolean getMyBoolean() {
        return myBoolean;
    }
    public void setMyBoolean(Boolean myBoolean) {
        this.myBoolean = myBoolean;
    }    
}

package test.java;

import static org.junit.Assert.*;
import main.java.util.MyClass;

import org.junit.Test;

public class MyClassTest {

     @Test
     public void testMyBoolean() {

        MyClass myClass = new MyClass();
        assertTrue(myClass.getMyBoolean());
        assertFalse(myClass.getMyBoolean());
    }
}

getMyBoolean() returns false so the assertFalse() method will return normally and assertTrue() method will fail.


       assertNull () / assertNotNull ()

The methods test a variable in order to check if it is null or not null. 

package test.java;

import static org.junit.Assert.*;
import main.java.util.MyClass;

import org.junit.Test;

public class MyClassTest {

     @Test
        public void testGetMyObject() {

            MyClass myClass = new MyClass();
            assertNull(myClass.getMyObject());
            assertNotNull(myClass.getMyObject());
        }
}

The method assertNotNull () returns an opposite result to assertNull () method and will throw an exception if a null value is passed to it and returns normally if a non- null object is used.

       assertSame () / assertNotSame ()

The methods assertSame() and assertNotSame() test if two object references point to the same object or not. 

package test.java;

import static org.junit.Assert.*;
import main.java.util.MyClass;

import org.junit.Test;

public class MyClassTest {

    @Test
    public void testGetMySameObject() {
        MyClass myClass = new MyClass();
  
        assertSame   (myClass.getMySameObject(),
                myClass.getMySameObject());

        assertNotSame(myClass.getMySameObject(),
                myClass.getMySameObject());
    }
}

If the two references points to the same object the assertSame()  method will return normally otherwise an exception will be thrown. The method assertNotSame()  is the opposite method of assertSame().

       assertThat ()

Matchers were added by the framework Hamcrest within JUnit 4.8.2 version. The method assertThat() has the following signature:

assertThat (Object o, Matcher matcher){

….}

package test.java;

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.junit.Test;

public class MyClassTest {

        @Test
        public void testMyMatchers() {
            assertThat("my matcher", is("my matcher"));
            assertThat(100, is(100));
        }
}

The result is:

The assertThat() method takes the object Matcher for implementation and this object determines if the test passes or fails.

The method org.hamcrest.CoreMatchers.is() is used to create a Matcher. If the two compared values are equal then the Matcher returned by is() is true otherwise is false.

The method assertThat () will throw an exception if the Matcher returns false otherwise will return normally.

4.3 Test Case

A Test Case is used to group together tests that check common behaviors. Test classes are defined in JUnit 4.x version by annotating a method with @Test and in 3.x version by extending the TestCase class.

A test is represented by a test method and a test case by the class that contains all the @Test annotated test methods.

Example: see the examples from previous chapters.

4.4 Test Execution order

With JUnit 4.x version the order of the test methods execution can be predictable. The order can be specified by annotating with:

       @FixMethodOrder

with the values:

 @FixMethodOrder(MethodSorters.DEFAULT) – deterministic but not predictable order based on an internal comparator (hashCode).
 @FixMethodOrder(MethodSorters.NAME_ASCENDING) - ascending lexicographic order of the names of the methods

 @FixMethodOrder(MethodSorters.JVM) - pre 4.11 way of depending on reflection based order that uses JVM defaults ( may  differ each time ). 

import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.JVM)
public class ABCTest {

    @Test
    public void b_test() {
    System.out.println("b_test called..");
    }

    @Test
    public void a_test() {
    System.out.println("a_test called..");
    }

    @Test
    public void c_test() {
    System.out.println("c_test called..");
    }     
}

The output is:

c_test called..

a_test called..

b_test called..

The test result is:

In case of MethodSorters.NAME_ASCENDING:

import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ABCTest {

    @Test
    public void b_test() {
    System.out.println("b_test called..");
    }

    @Test
    public void a_test() {
    System.out.println("a_test called..");
    }

    @Test
    public void c_test() {
    System.out.println("c_test called..");
    }     
}

The output is:

a_test called..

b_test called..

c_test called..

The test result is: 

Tests should not depend on other tests and should not imply any order under normal circumstances. The @FixMethodOrder annotation can allow us to fix our tests until dependency exists and eliminate it.

 

Like us on Facebook