Thursday, August 27, 2009

Java EE and Cloud Computing

I would like to share this interesting article on Java EE and Cloud Computing.

Monday, August 10, 2009

JUnit 4.0

Junit 4.0 is very different from its previous versions. I present the features followed by examples.


JUnit 4.0 features:

  • Uses annotations and makes life very easy.
  • Test Class DOES NOT have to extend TestCase.
  • Need to manually do "import static org.junit.Assert.*" to get all the methods like AssertFalse and AssertTrue as the Test class does not extend TestCase.
  • All methods that needed to be tested should be decorated with @org.junit.Test annotation and you can use any method name.
  • @Test notatation takes an expected parameter which can be used to specify the exception the method should throw.eg: @Test(expected=IndexOutOfBoundsException.class) The test fails if the expected exception is not thrown.
  • To not test a particular method , decorate it with the annotation @org.junit.Ignore
  • Can specify a timeout for a method, if the method runs for a longer time, it fails. eg: @Test(timeout=1)- AssertEquals can test arrays, so we don't need to iterate over contents of array.
  • Can use annotations to specify test fixtures.
  • There are 2 Class level fixtures: @BeforeClass and @AfterClass. These are run only once before or after the tests in the class are run. Note: Can create multiple @BeforeClass fixtures though the order of running them cannot be currently
    specified.
  • There are 2 Method level fixtures: @Before and @After. These are run before or after running every test (method) in the class.
  • Can use annotations to specify test suites.
    @RunWith(Suite.class)
    @Suite.SuiteClasses( { <YourTestClass1>.class,[<YourTestClass2>.class] })
    public class <SuiteName> {
    }
  • Introduces a new runner called Parameterized. It allows the same tests to be run with different data. One of the examples below shows how to run Parameterized test. To enable this do the following:
    • Have the annotation @RunWith(value = Parameterized.class) for the Test Class
    • Have a public static method that returns a Collection for data. Each element of the collection must be an Array of the various paramters used for the test.
    • Provide a public constructor for the test class that uses the parameters.

Examples:

Java code on which the tests have to be run


import java.util.HashMap;
import java.util.Map;

public class SimpleExample {

private Map<Integer, Employee> emp;

public SimpleExample() {
emp = new HashMap<Integer, Employee>();
}

public void addEmployee(String name, int id) {
Employee e = new Employee(name,id);
emp.put(id, e);
}

public String getEmployeeName(int id) throws EmployeeException{
if (!emp.containsKey(id)) {
throw new EmployeeException("No Employee with the id " + id);
}
return emp.get(id).getEmpName();
}

public int getNumberofEmployees(){
return emp.size();
}


}

class Employee {
private String empName;
private int empID;

Employee(String name, int id) {
empName = name;
empID = id;
}

public String getEmpName() {
return empName;
}

public int getEmpID() {
return empID;
}
}

public class EmployeeException extends Exception {

private static final long serialVersionUID = 1L;

EmployeeException(String ex) {
super(ex);
}

}


Example 1: JUnit 4.0 test cases for the above class


import static org.junit.Assert.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

public class SimpleExampleJUnitTest {

private static SimpleExample se;
private static final String NAME1 = "foo";
private static final String NAME2 = "bar";

@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("setUpBeforeClass: run only once");
se = new SimpleExample();
se.addEmployee(NAME1, 1);
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("tearDownAfterClass: run only once");
se = null;
}

@Before
public void setUp() throws Exception {
}

@After
public void tearDown() throws Exception {
}

@Test
public void addEmployeetTest() {
se.addEmployee(NAME2, 2);
assertEquals(se.getNumberofEmployees(),2);
}

@Test
public void getExisitingEmployeeNameTest()
throws EmployeeException {
assertEquals(se.getEmployeeName(1),NAME1);
}

@Test(expected=EmployeeException.class)
public void getNonExisitngEmployeeNameTest() throws EmployeeException {
se.getEmployeeName(10);
}

@Ignore
public void getAllEmployeesTest() {
//Not yet implemented.
}
}


Example 2: Parameterized JUnit 4.0 test case


import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.Collection;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(value = Parameterized.class)
public class SimpleExampleParameterizedJUnitTest {

private SimpleExample se;
private String name;
private int id;

public SimpleExampleParameterizedJUnitTest(String name,int id) {
this.name = name;
this.id = id;
}

@SuppressWarnings("unchecked")
@Parameters
public static Collection data() {
Object[][] data = new Object[][] {
{ "foo", 1}, {"bar",2},{"foobar",3}};
return Arrays.asList(data);
}

@BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("setUpBeforeClass: run only once");
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("tearDownAfterClass: run only once");
}

@Before
public void setUp() throws Exception {
System.out.println("setUp: run before every test");
se = new SimpleExample();
}

@After
public void tearDown() throws Exception {
System.out.println("teatDown: run after every test");
se = null;
}

@Test
public void addEmployeetTest() {
se.addEmployee(name,id);
assertEquals(se.getNumberofEmployees(),1);
}

@Test
public void getExisitingEmployeeNameTest()
throws EmployeeException {
se.addEmployee(name,id);
assertEquals(se.getEmployeeName(id),name);
}

@Test(expected=EmployeeException.class)
public void getNonExisitngEmployeeNameTest() throws EmployeeException {
se.getEmployeeName(id+1);
}

@Ignore
public void getAllEmployeesTest() {
//Not yet implemented.
}
}