Thursday, December 8, 2011

Using a Singleton

Below is an example of a Singleton used to decrement a counter variable:

package singleton;
public class Counter {
   private static Counter instance;
   private int count;


   private Counter() {
   }


   public static synchronized Counter getInstance() {
      if (instance == null) {
          instance = new Counter();
      }
      return instance;
   }


   public synchronized void decrement() {
       count--;
       if( count<0 ) {
          count=0;
       }
   }


   public synchronized int getCount() {
       return count;
   }


   public synchronized void setCount(int countValue) {
       count = countValue;
   }
}

Test class for the singleton above:

package singleton;

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

public class CounterTest {
    private Counter counter1 = null, counter2 = null;

    @Before
    public void setUp() throws Exception {
       counter1 = Counter.getInstance();
       counter2 = Counter.getInstance();
    }

    /**
     * Test case to ensure that the getInstance Method
     * returns a non null object and to ensure
     * that getting 2 instances of Counter results in
     * the same object being returned.
     */
    @Test
    public void testGetInstance() {
       counter1 = Counter.getInstance();
       assertNotNull(counter1);
       counter2 = Counter.getInstance();
       assertNotNull(counter2);
       assert (counter1 == counter2);
    }

    /**
     * Test case that tests decrementing the count variable and
     * also ensures that both counter1 and counter2
     * returns the same count value.
     */
    @Test
    public void testDecrement() {
       counter1.setCount(20); 
       counter1.decrement();
       assert (counter1.getCount() == 19);
       assert (counter2.getCount() == 19);
    }

    /**
     * Tests that both instances of the Count returns
     * the same count value.
     */
    @Test
    public void testGetCount() {
       int count1 = counter1.getCount();
       int count2 = counter2.getCount();
       assert (count1 == count2);
       counter2.setCount(100);
       count1 = counter1.getCount();
       assert (count1 == 100);
       count2 = counter2.getCount();
       assert (count1 == count2);
    }

   /**
    * Tests that we are allowed to set the count variable
    * and that another instance reading that variable will
    * result in the correct value being returned. */
    @Test
    public void testSetCount() {
       counter2.setCount(100);
       int count1 = counter1.getCount();
       assert (count1 == 100);
    }
}