Statically Typed

because Hindley-Milner rocks

Testing API consistency with Reflection and Unit tests


When developing an API for a customer the most important thing is documentation other than it working properly.  Part of that documentation is the code itself.  I know I’ve been personally frustrated by code that contains all sorts of variant naming conventions like get_Item(), getNextItem(), and getlastitem().  Which one does a particular class use at any given time?  Ugh!

Since I’ve been developing an API for a larger project I’ve made unit tests of the API naming conventions a part of my project.  It’s fairly simple, watch:

public interface Location {
    public String getName()
    public String getStreet()
    public String getNumber()
    public String getSize()
    public String getZoning() 

    public void setName(String _name)
    public void setStreet(String _street)
    public void setNumber(String _number)
    public void setSize(String _size)
    public void setZoning(String _zoning)
}

In this example I’m just creating a very basic interface with simple accessors.  For classes let me assume that I have the most basic and simple class which merely implements the method with no logic what-so-ever.  Then testing it for API consistency boils down to writing a very simple test as such:

@test
public void test_Accessors() {
    Location myObject = new FooLocation();

    HashMap<Method,Method> methods = mapAccessors( FooLocation.class );
    for( Entry accessors : methods.entrySet() ) {
        String name = accessors.getKey().getName();
        accessors.getKey().invoke( myObject, name );
        assertEquals( accessors.getValue().invoke( myObject ), name );
    }
}

which checks that the name returned from the get functions matches the name of the set function.  However, this test calls this function:

protected HashMap<Method,Method> mapAccessors(Class<?> _class) throws Exception {
    //this could be its own function if maps combined
    HashMap<String,Method> getMethods = new HashMap<String,Method>();
    HashMap<String,Method> setMethods = new HashMap<String,Method>();
    for( Method item : _class.getMethods() ) {
        String methodName = item.getName();
        if( methodName.startsWith( "get", 0 ) ) {
            getMethods.insert( methodName, item );
        } else if( methodName.startsWith( "set", 0 ) ) {
            setMethods.insert( methodName, item );
        }
    }

    HashMap<Method,Method> output = new HashMap<Method,Method>();
    for( Entry keyValue : setMethods.entrySet() ) {
        output.insert( keyValue.getValue(), getMethods.get( "get" + keyValue.getKey().substring( 3 ) ) );
    }

    return output;
}

Granted I’ve taken the liberty to only use java.lang.String in this example but it is at the very least an efficient manner of testing things do exist.

item.getName()
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on February 22, 2010 by in Unit Testing.
%d bloggers like this: