Friday, July 03, 2009

Android: Testing on the Android platform - Hamcrest









This document can be read in Google Docs (http://docs.google.com/View?id=ddwc44gs_193f2v698g9), cut and paste link if you have problems accessing it.







We used a custom Comparator in the previous post to be able to compare Strings content in our mock object's method invocations.






While this method is valid a more generic approach would be to introduce hamcrest, a library of matcher objects (also known as constraints or predicates) allowing 'match' rules to be defined declaratively, to be used in other frameworks. Hamcrest also provides adaptors for EasyMock 2.



We will be revisiting our previous example introducing hamcrest for our matchers.


Hamcrest matchers



Hamcrest comes with a library of useful matchers. Here are some of the most important ones.

    · Core
          o anything - always matches, useful if you don't care what the object under test is
          o describedAs - decorator to adding custom failure description
          o is - decorator to improve readability - see "Sugar", below
    · Logical
          o allOf - matches if all matchers match, short circuits (like Java &&)
          o anyOf - matches if any matchers match, short circuits (like Java ||)
          o not - matches if the wrapped matcher doesn't match and vice versa
    · Object
          o equalTo - test object equality using Object.equals
          o hasToString - test Object.toString
          o instanceOf, isCompatibleType - test type
          o notNullValue, nullValue - test for null
          o sameInstance - test object identity
    · Beans
          o hasProperty - test JavaBeans properties
    · Collections
          o array - test an array's elements against an array of matchers
          o hasEntry, hasKey, hasValue - test a map contains an entry, key or value
          o hasItem, hasItems - test a collection contains elements
          o hasItemInArray - test an array contains an element
    · Number
          o closeTo - test floating point values are close to a given value
          o greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo - test ordering
    · Text
          o equalToIgnoringCase - test string equality ignoring case
          o equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace
          o containsString, endsWith, startsWith - test string matching



hasToString matcher


Let's create a matcher to replace stringCmp. EasyMock2Adapter is an adapter class provided by hamcrest.










import org.hamcrest.integration.EasyMock2Adapter;

import org.hamcrest.object.HasToString;   





    /**


     * Create an {@link EasyMock2Adapter} using a
     * {@link HasToString.hasToString}


     *

     * @param <T> The original class of the arguments

     * @param o The argument to the comparison

     * @return o

     */

    public static <T> T hasToString(T o) {

        EasyMock2Adapter.adapt(
            HasToString.hasToString(o.toString()));


        return o;

    }




testTextChanged

Now, the watcher mock object checks will include this matcher:










    watcher.beforeTextChanged(hasToString(sar[i-1]),

       eq(0), eq(sar[i-1].length()), eq(sar[i].length()));

    watcher.onTextChanged(hasToString(sar[i]),

       eq(0), eq(sar[i-1].length()), eq(sar[i].length()));

    watcher.afterTextChanged(

       hasToString(Editable.Factory.getInstance()
       .newEditable(sar[i])));




Conclusion


We have introduced hamcrest that makes a great number of matchers and the ability to create new ones and adapt them to be used by EasyMock.




Copyright © 2009 Diego Torres Milano. All rights reserved.


















No comments: