Thursday, October 25, 2012

How To Write A Junit Test When A Method Returns Multiple Values

So you have a class like this :

public class PersonUtils {
 static List<Person>  persons = new ArrayList<Person>();

 static List<Person> getPersonList(){
  Person p1 = new Person();
  p1.setId(0);
  p1.setName("Batman");
  
  Person p2 = new Person();
  p2.setId(1);
  p2.setName(null); //bad!! we want person to have a name!

  persons.add(p1);
  persons.add(p2);
  
  return persons;
 }
 
}

class Person{
 private String name;//cannot be null - must check in JUnit !!!
 private int id;
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
}

And then your boss asks you to write unit tests to test Person name because a lot of them are having their names as null!

And now you ponder! "Hmmm.. Writing a JUnit Test which loops through and tests each person attributes is bad! I need to come up with something more clean"

Thankfully JUnit  provides you with........(drum rollllllll).......
Parameterized Tests

Now how the heck do we write a parameterized Test case ? It looks like .......

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

 Person person ;
 
 @Parameters
 public static Collection<Object[]> data(){
  List<Person> persons = PersonUtils.getPersonList();
  Object[][] data = new Object[persons.size()][1];
  
  for (int i = 0; i < data.length; i++) {
   data[i][0] = persons.get(i);
  }
  
  return Arrays.asList(data);
 }
 
 public PersonListTest(Person p) {
  this.person = p;
 }

 @Test
 public void testPersonNameNotNull() {
  assertNotNull("Person name cannot be null!" + person.getName(),
    person.getName());
 }
 
 //other tests go here
 
}

  1. The data() method does all the dirty work.
  2. This data() prepares a 2d array which is then fed one by one to the Test as a whole.
  3. See that PersonListTest(Person) constructor? That's where its fed.
  4. After that, each of the @Test methods in this class are run..
One last note.. You may have to take the appropriate jar version of junit for Parameterized class to be present

And in case you are wondering how I formatted this code , I did it using this.

No comments:

Post a Comment