Sunday, 10 February 2013

Testing Private methods using Reflection

Without entering into a debate of why or why not private methods should be directly tested, here are the various steps involved in testing a private method using Java Reflection.

Scenario 1 : The private method has no input parameters, operates on a private variable and returns a value.

The class to be tested.

package com.john.exeriment;

/**
 * The class to be tested.
 *
 */
public class App
{
private String name= "John";
private int numCharactersInName = 0;
 
public int getNumCharactersInName() {
return numCharactersInName;
}
private int getSizeOfName()
{
numCharactersInName = name.length();
return numCharactersInName;
}
public static void main( String[] args )
 {
App app = new App();

System.out.println(" The size of the name is " + app.getSizeOfName());

   }
}
-------------
JUNIT Class

package com.john.exeriment;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest extends TestCase
{
    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest( String testName )
    {
        super( testName );
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite()
    {
        return new TestSuite( AppTest.class );
    }

/**
* Test method operates on the private field using its default value
**/
public void testAppMethod() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchFieldException
    {
    App myApp = new App();
        Method m = myApp.getClass().getDeclaredMethod("getSizeOfName", null);
        m.setAccessible(true);
        Integer size = (Integer) m.invoke(myApp, null);

    assertTrue( "Size should be ", size == myApp.getNumCharactersInName());
    }

We assume the method getNumCharactersInName() has been tested.


/**
* Test case modifies the private field of the class using Reflections before testing the required private method.
**/
public void testAppField() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
    {
    App anotherApp = new App();
    Field field = anotherApp.getClass().getDeclaredField("name");
    field.setAccessible(true);
    field.set(anotherApp, "Testing!!!");
   
    Method m = anotherApp.getClass().getDeclaredMethod("getSizeOfName", null);
         m.setAccessible(true);
         Integer size = (Integer) m.invoke(anotherApp, null);
   
    assertEquals( "Size should be", 10,  size, 0.000001 );
    }

}



Scenario 2 : The private method takes a String as an input parameter and does not return a value.

We add the following method to our class.


private void getSizeOfName(String name)
{
numCharactersInName = name.length();
}


And to test it, we have the following JUNIT test.

public void testAppMethodWithInputParam() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
    App myApp = new App();
   
    // The parameter type
    Class[] parameterTypes = new Class[1];
        parameterTypes[0] = String.class;
        
        // The parameter value
        Object[] parameters = new Object[1];
        parameters[0] = "Cricket";
        
        Method m = myApp.getClass().getDeclaredMethod("getSizeOfName", parameterTypes);
        m.setAccessible(true);
        m.invoke(myApp, parameters);

    assertEquals( "Size is greater than 0", 7, myApp.getNumCharactersInName());
  }


In the test, we set up a String variable which we initialise to the value Cricket, and test if the method initialises the numCharactersInField correctly to 7 characters.

Thus, testing private methods via Reflection is a straightforward process and should be used if there are key parts of the business logic embedded in private methods.

Monday, 21 January 2013

Parsing Strings in PL/SQL


Consider a scenario where you need to parse a VARCHAR2 value which is delimited by a special character such as a comma. Rather than parse the entire input and search for the start and end of each sub-string, use the apex_util.string_to_table() that is available in Oracle 10G and 11G

A typical usage example would be as follows:

DECLARE

variable_array_to_hold_values apex_application_global.vc_arr2;
variable_test VARCHAR2(100) := 'show:me:a:parser';

 BEGIN

    variable_array_to_hold_values := apex_util.string_to_table(variable_test, ':');
     FOR i IN 1..variable_array_to_hold_values.COUNT
     LOOP
         DBMS_OUTPUT.PUT_LINE(' Value is ' || variable_array_to_hold_values(i));
     END LOOP;
 END;
 /

And the result would be
 Value is show
 Value is me
 Value is a
 Value is parser

Thursday, 17 January 2013

Apache Commons Lang Library : Managing Strings without NullPointers

The Apache Commons Lang 3.0 package is a useful set of utilities and interface definitions for String and Character manipulation. With respect to String manipulation, the StringUtils, StringEscapeUtils, RandomStringUtils, Tokenizer, WordUtils classes provide a number of utility methods for manipulating and managing String.

The StringUtils class has some interesting functions such as 
  • IsEmpty/IsBlank - checks if a String contains text. The main difference between IsEmpty and IsBlank is that that IsBlank also checks for whitespaces while IsEmpty doesn't. 
  • Trim/Strip - removes leading and trailing whitespace
  • Equals - compares two strings null-safe
  • startsWith - check if a String starts with a prefix null-safe
  • endsWith - check if a String ends with a suffix null-safe
  • IndexOf/LastIndexOf/Contains - null-safe index-of checks
  • IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut - index-of any of a set of Strings
  • ContainsOnly/ContainsNone/ContainsAny - does String contains only/none/any of these characters
  • Substring/Left/Right/Mid - null-safe substring extractions
  • SubstringBefore/SubstringAfter/SubstringBetween - substring extraction relative to other strings
  • Split/Join - splits a String into an array of substrings and vice versa
While these functions may appear similar to the ones provided by the String package itself, the StringUtils versions are null safe thus eliminating the possiblity of those horrible NPEs. It should be noted that a null input will return null without throwing any exception.

Saturday, 12 January 2013

The Kogan Agora 10 inch Tablet : A user review

Recently purchased a two month old Kogan Agora Tablet powered by a 1, GHz single-core ARM Cortex A8, running an Android 4.0.4 ICS. It has 16 GB storage expandable to 32 GB, a sleek 10 inch screen with a 1024x768  LCD display, weighs 600gms  and is about 12 mm thick. Priced at less than $200 ( I got it for less than $150 off eBay), it is an excellent entry level device into the world of tablet computing. 
My requirements were modest at best. I needed a tablet that could play some kiddie games for my 2 year old, browse the net and handle some rough treatment at the hands of my 2 year old. Suffice to say the tablet so far meets all my requirements.
On the plus side, it has a sleek look, is light and easy to hold and use. The pinch and zoom feature that has been maligned in several reviews, worked well for me. Simple games like Talking Tom work well and give an indication of how well the microphone and the speakers work. 
On the negative side, the twin cameras produce disappointing results as compared to the photos taken by the Samsung tablets and multi-tasking is definitely not one of the tablet's strong features. Even loading two sites at the same time can make the device slow and unresponsive but with the latest models offering a dual core processor this problem could well be a thing of the past.
Even with its relative slow performance, if I went back and evaluated it against my original requirement of acquiring an entry level tablet device which is fully functional, it is a great buy and yes I won't feel bad at all if my 2 year old accidentally breaks it.
Finally, a handy tip, get yourself a leather case and a screen protector if you intend to share the device with your kids and if still unsure have a read of this review  and perhaps this one (for more technical comparisons) from June 2012, which benchmarks the Tablet running Android 4.0.3 ICS (the previous version to the one I have installed).