Monday, 17. September 2007

behaviour driven development with beanSpec

first of all, this is no introduction to Behaviour Driven Development, as there are already many great articles and informations available, so the world doesn't need another entering guide yet.

this post is rather an introduction to beanSpec, a little tool for writing specifications in the sense of BDD in Java. beanSpec tries to provide a clear conceptual model that is easy to capture and apply (if you've seen RSpec so far, you will immediately feel familiar with beanSpec, because the conceptual model is almost the same).

beanSpec by example

let's dive into beanSpec by example - specifying the behaviour of java.util.Stack (ok, that's not the most fancy example, but it will serve the purpose of an introduction very well. in addition to that, you can compare it to the given @Stack example at RSpec's home and see the conceptual similarities).

we start the example with a new specification class, as all specifications within beanSpec start by extending beanSpecs class Spec:

public class StackSpec extends Spec {
}

that was easy!
now we want to specify the behaviour of a non empty Stack. therefore we simply have to define a method that will specify that context, so we should name our method according to the particular context ('a non empty Stack').

public class StackSpec extends Spec {

  @Specification
  public void a_non_empty_Stack(){
  }
}

i used a rather unusual style for the methods name (it increases the readability of the Spec in my opinion). of course you could use good old camel case style whenever you want to! further on, you may have noticed the annotation @Specification. it's for marking only those methods within your Spec, which should be evaluated, since you are free to have arbitrary helper methods within your Spec.

context

next we firstly have to describe the context within the method's body, that is a non empty Stack:

...
@Specification
public void a_non_empty_Stack(){
 
  final String lastItemAdded = "elem 3";
        
  Stack aNonEmptyStack = is(
            
    new DescriptionOf <Stack>(){
            
      public Stack isDescribedAs(){
        Stack<String> stack = new Stack<String>();
        stack.push( "elem 1" );
        stack.push( "elem 2" );
        stack.push( lastItemAdded );
        return stack; } } );
  ...

we've pushed three elements onto the Stack. Note, that we've defined the last pushed element outside the description, since we will refer to that element in the following statements.

statements

now we are ready to specifiy the behaviour of this context within the method. therefore we declare every expected behaviour in a textual style, followed by one or more operations and statements, that will specify the behaviour programmatically in a checkable way:

...
  it( "should not be empty" );
  state( aNonEmptyStack ).should( not( be( empty() ) ) );

  // or alternatively: state( aNonEmptyStack.empty() ).should( be( true ) );
...

predicates

using predicates for defining the claimed behaviour (that is the expression inside the called should() method) gives you the freedom to combine such predicates in any combinations that makes sense to your specific context. since it's very easy to write your own predicates, it's even possible to come up with your own set of domain specific predicates, giving you the chance to build a kind of domain specific vocabulary for your specifications.

for example we could be in need of a predicate that checks the given result of a statement against a regular expression, so that we could state the following:

...
it( "contains only elements that start with 'elem'" );
for( Object elem : aStackWithThreeElements.subList(0, 3) ){
  state( elem ).should( match( "elem.*" ) );
}

of course this special predicate makes no sense in the actual context (and even would fail, since our last pushed element isn't compliant in regard to the stated pattern), but for demonstrations sake here's the predicate we would have to come up with:

public class MatchPredicate extends AbstractPredicate {

  private String pattern;
    
  public MatchPredicate( String pattern ){
    this.pattern = pattern;
  }
    
  public boolean isValidFor(Object bean) {        
    return bean.toString().matches( pattern );
  }

  public static Predicate match( String pattern ){
    return new MatchPredicate( pattern );
  }
}

now that we've seen how easy it is to extend beanSpec's vocabulary with domain specific predicates, let's have a second look at some of the predefined ones, that you can use out of the box:

...
  it( "should return the top item when sent #pop" );
  state( aNonEmptyStack.pop() ).should( be( lastItemAdded ) );
        
  it( "should return the top item when sent #peek" );
  state( aNonEmptyStack.peek() ).should( be( lastItemAdded ) );
        
  it( "should NOT remove the top item when sent #peek" );
  aNonEmptyStack.peek();
  state( aNonEmptyStack.peek() ).should( be( lastItemAdded ) );
        
  it( "should remove the top item when sent #pop" );
  state( aNonEmptyStack.pop() ).should( be( lastItemAdded ) );
  while( ! aNonEmptyStack.isEmpty() ){
    state( aNonEmptyStack.pop() ).should( not( be( lastItemAdded ) ) );
  }
...

you may have asked yourself why you are able to call the method pop() in the first statement, and then stating in the next one, that the top level element is even the lastItemAdded (but pop() should have removed that element in the previous statement, right?).

this is one of the mechanics of beanSpec: every single specification statement (starting with it() ) gets a fresh new Stack object according to the definition at the start of the method. you then can operate on that object within your operations and state() expressions and change it's state if necessary. as soon as you start with a new specification statement (initiated by the next it() call) you'll again operate on a new instance.

specification templates

let's assume we want to specify the behaviour of Stack in another context (i.e. empty Stack, full Stack, Stack with one element left to full, ...).
it's very likely that you have to repeat some of your statements. according to the DRY principle, beanSpec gives you the chance to define one ore more so called specification template methods, that can be refered in your concrete context specifications:

...
// specification template
public void a_non_empty_Stack( Stack aNonEmptyStack, String lastItemAdded ){       
           
  it( "should not be empty" );
  state( aNonEmptyStack ).should( not( be( empty() ) ) );
  ...
}

// another specification template
public void a_non_full_Stack( Stack<Object> aNonFullStack ){

  it( "should add to the top when sent #push" );
  Object newlyPushedElement = aNonFullStack.push( "new Element" );
  state( aNonFullStack.peek() ).should( be( newlyPushedElement ) );
}

@Specification
public void a_stack_with_3_elements(){
        
  final String lastItemAdded = "elem 3";
        
  Stack aStackWithThreeElements = is(
            
    new DescriptionOf <Stack>(){
            
      public Stack isDescribedAs(){
        Stack<String> stack = new Stack<String>();
        stack.push( "elem 1" );
        stack.push( "elem 2" );
        stack.push( lastItemAdded );
        return stack; } } );
        
  itShouldBehaveLike( "a_non_empty_Stack", sharing( lastItemAdded ) );
        
  itShouldBehaveLike( "a_non_full_Stack" );
        
  // additional Statements
  it( "should be of size 3" );
  state( aStackWithThreeElements ).should( have( size( 3 ) ) );
  ...
}

as you can see, there are two specification templates. a specification template takes at least one argument - the object that must stand the stated specifications within the template. should there be other information that should be shared, they will follow as additional arguments.
now you can refer to those specification templates by stating itShouldBehaveLike, followed by the name of the template.
note, that the 'object to specify' is implicitly populated by beanSpec itself. all additional arguments that should be shared with the template have to be populated via an explicit sharing() statement.

specification verification summary

having specified the behaviour (and implemented Stack), we can check if Stack behaves as expected by running the StackSpec (at the moment there's only a ConsoleRunner).
beanSpec gives a summary of the evaluated specification, making it easy to read the whole specification in a textual form and recognize any misbehaviour, should one of the stated specifications should fail.

STACKSPEC
---------------

a_stack_with_3_elements
 - should not be empty : ok
 - should return the top item when sent #pop : ok
 - should return the top item when sent #peek : ok
 - should NOT remove the top item when sent #peek : ok
 - should remove the top item when sent #pop : ok
 - should remove the top item when sent #pop : ok
 - should remove the top item when sent #pop : ok
 - should add to the top when sent #push : ok
 - should be of size 3 : ok
 - contains only elements that start with 'elem' : failed

statements : 10, ok : 9, failure : 1

an_empty_Stack
 - should add to the top when sent #push : ok
 - should complain when sent #peek : ok
 - should complain when sent #pop : ok

statements : 3, ok : 3, failure : 0


Specs : 2, total statements : 13, ok : 12, failure : 1

that's it so far - a short introduction to beanSpec.
i would love to hear some feedback from you, should it be criticism or feature requests - any feedback is appreciated!
 

Posted by mario.gleichmann at 00:05:53 | Permanent Link | Comments (2) |

Saturday, 25. August 2007

mimicry in action II - dynamically implement an interface using Dynamic Proxy

this entry is the continuation of part 1, where we saw how to leverage Dynamic Proxy in order to let an object appear as if it would implement an arbitrary interface as long as it offers the same methods.

extensions

in this second part we'll extend the solution in order to map required methods of an interface to an object's methods, even if those methods partially bear another name (or offer sybtypes of the required arguments, even if they are placed in a different order).

a fluent interface

one fundamental goal is a simple and fluent api in order to support ease of use, allowing a simple and declarative style of usage - well, we'll see ...

for clarity, we will modify our example - imagine that class Foo has no longer a matching method echo(), but a method called reverb():

public class Foo {
    public String say( String msg ){
        return "foo said " + msg;
    }
    ...
}

now we want to (have to) map the required method echo() of interface IBar to reverb(). we'll start with thinking about a possible api extension and have some thoughts about it's implementation afterwards. a possible way to express the mapping could look like this:


barClient.speakTo(
  foo.as( IBar.class, map( "echo" ).to( "reverb" ) ) );
 

mapping method names

as you can see, we only extend the signature in order to push one (or more) mappings to the proxy, using a statically imported method map(). therefore we will use varargs in the following solution, so it's completely free to the client to apply as many mappings as needed:

public class InterfaceMimic
  implements InvocationHandler{

    public static <I> I mimic(
      Object bean,
      Class<I> asInterface,
      MethodMapping...mappings ){
        return
            (I) Proxy.newProxyInstance(
                bean.getClass().getClassLoader(),
                new Class[]{asInterface},
                new InterfaceMimic( bean, mappings ) );
    }
    
    public static MethodMapping map(
      String interfaceMethod ){
        return
          new MethodMapping( interfaceMethod );
    }
    
    private MethodMapping[] mappings =
      new MethodMapping[0];
   
    private Object proxee = null;
    
    public InterfaceMimic(
      Object proxee,
      MethodMapping...mappings ){

        this.proxee = proxee;
        this.mappings = mappings;
    }
    ...
}

we're not finished yet. you surely saw the new type MethodMapping, which now extends the signature of method mimic() (formerly as() ) as a vararg.

MethodMapping

this type will hold the whole information about the mapping. you also saw the static factory method map(), which will create a new instance of MethodMapping initializing it with the name of the method required by the interface. what's left is the mapping link to the method which have to be called on the object:

public class MethodMapping {

    private String interfaceMethod = null;
    private String beanMethod = null;
    
    public MethodMapping(
      String interfaceMethod ){
       
      this.interfaceMethod = interfaceMethod;
    }

    public MethodMapping to(
      String beanMethod, Class...argTypes ){
        this.beanMethod = beanMethod;
        return this;
    }

    protected boolean matches(
      Method method ){...}

    protected Object callMappedMethodOn(
      Object bean, Method method, Object[] args ) {...}
    ...
}

now we only have to extend the proxy in order to hold the mappings and ask if there's one when intercepting a method:

public class InterfaceMimic
  implements InvocationHandler{
...
    public Object invoke(
      Object proxy,
      Method method,
      Object[] args )
        throws Throwable {

        MethodMapping mapping =
          findMappingFor( method );
        
        return
            mapping != null ?
                mapping
                  .callMappedMethodOn(
                    proxee, method, args ) :
                callProxy( method, args );
    }

    private Object callProxy(
      Method method, Object[] args) {
        try {
            return
                proxee
                    .getClass()
                    .getDeclaredMethod(
                      method.getName(),
                      method.getParameterTypes() )
                    .invoke( proxee, args );
        }
        catch (Exception e) {
            throw new RuntimeException( e );
        }
    }

    private MethodMapping findMappingFor(
      Method method ){
        for( MethodMapping mapping : mappings ){
            if( mapping.matches( method ) )
              return mapping;
        }
        return null;
    }
}

as you can see, we first try to find a matching MethodMapping. if one exists, we call the mapped method on the object. if not, we try to call a method on the object with the same name as the required one. that's all.

of course you could now extend type MethodMapping in order to additionally gathering information about the argument types of the mapped method and / or their different order, like so:

// reorderArgs will show on the first position,
// to which argument position the first interface
// argument will map, and so on ...
foo.as(
  IBar.class,
  map( "add" )
    .to( "calc", BigDecimal.class, int.class, String.class )
    .reorderArgs( 3, 2, 1 ) ) ); 

i'll leave this exercise to you. it should be no big challenge at all. if you want to see one possible solution, take a look at the open source project Bricks4J. i comitted the complete source along with a unit test in the current cvs branch, which will show you the correct usage.

conclusion

as you now have seen, Dynamic Proxy is a valuable tool when it comes to mimic interfaces. you can easily make an object appear as if it would implement an interface, even if this object methods doesn't match exactly by name or argument types.
of course you'll face a trade off - sometimes it might by easier and more comprehensible simply to implement an adaptor for an interface than using a bulk of mappings. so it's up to you - as always - to choose the right 'weapon' ...

Posted by mario.gleichmann at 21:25:14 | Permanent Link | Comments (2) |

Saturday, 18. August 2007

mimicry in action - dynamically implement an interface using Dynamic Proxy

do you ever had that problem, that a class asks for a certain interface that your client class hasn't implemented, although all of the interfaces required methods are present in that class?

to make things clear, here's a little example:

first of all, here's a 'typical' interface (i deliberately use the prefix I to highlight that this one is an interface):

public interface IBar {
  public String echo( String s );
}

and here's a class, that will work with that interface:

public class BarCollaborator {
  public void speakTo( IBar bar ){
    System.out.println(
      "hello bar - " + bar.echo( "hello" ) );
  }
}

now you have a class Foo, that offers (by incident) a method with the same signature like the one required by the interface:

public class Foo {
  public String echo(String s) {
    return "foo " + s;
  }
}

although Foo accomplishes the contract of IBar, we can't apply an instance of Foo to BarCollaborator, because of the uncompatible types.

if you use a language like ruby, were a class doesn't rely on a certain type of a collaborator but rather on its interface (the methods an object offers - most of you will know that feature as 'duck typing': if it walks like a duck and if it talks like a duck than we will treat it like a duck), you certainly never will have a problem with that constellation.
but java is a different beast, using statically typed classes, where the type stays relevant during runtime. imagine if we could say something like this:

'apply this instance of Foo to BarCollaborator and make it appear as if it implements interface IBar'

in essence - something like

'use myFoo as IBar.class'

DynamicProxy to the rescue

well, this is possible - to a certain extend - with the help of a DynamicProxy. A DynamicProxy will 'mimic' a collection of interfaces (in this case we only need to mimic a single interface. in our conrete situation interface IBar ) to a client who will perform against those interfaces (in our concrete situation class BarCollaborator). when a client calls a method on that interface at runtime, the Proxy is called instead, having the chance to intercept the call and do whatever is necessery to complete it. regarding our context, we only try to detect the corresponding method on the target object (the instance of class Foo) and invoke it.

now here's the first simple implementation:

public class InterfaceBridgeProxy
  implements InvocationHandler {

  public static <T> T as( Class<T> asInterface, Object bean ){
    return
      (T) Proxy.newProxyInstance(
        bean.getClass().getClassLoader(),
        new Class[]{asInterface},
        new InterfaceBridgeProxy( bean ) );
  }

  private Object proxee = null;

  public InterfaceBridgeProxy( Object proxee ){
    this.proxee = proxee;
  }

  public Object invoke(
    Object proxy, Method method, Object[] args )
      throws Throwable {

    Method toInvoke = findMatchingMethod( method );
    return
      toInvoke != null?
        toInvoke.invoke( proxee, args ) : null;
  }

  private Method findMatchingMethod( Method method ){
    try {
      return
        proxee.getClass()
          .getDeclaredMethod(
            method.getName(),
            method.getParameterTypes() );
    }
    catch( Exception e) {
      return new RuntimeException(e);
    }
  }
}

now we can call BarCollaborator and apply an instance of Foo. using a static import for InterfaceBridgeProxy's static method as() will make the code a little more concise:

public static void main(String[] args) {
  BarClient barClient = new BarClient();
  Foo foo = new Foo();
  barClient.speakTo( as( IBar.class, foo ) );
}

of course we could apply a generic method as() directly to class Foo ...

public class Foo {
  public String echo(String s) {
    return "foo " + s;
  }

  public <T> T as( Class<T> interfaceMask ){
    return InterfaceBridgeProxy.as( interfaceMask );
  }
}

... making the example a little more readable:

  ...
  barClient.speakTo( foo.as( IBar.class ) )

the implemented functionality is general. now you are able to mimic an arbitrary interface for your collaborators, as long as your class offers the same methods required by the interface.

next time we will go one step further and see how to extend this mechanism to even map methods of your class to an interface which even has slightly different method names as long as the rest of the signature is matching.

stay tuned ... :o)

Posted by mario.gleichmann at 21:40:12 | Permanent Link | Comments (2) |

Thursday, 12. July 2007

jFIT - a little brother for FIT

it's common sense to test a single class inside of a unit test. you mostly hear about 'class under test' when talking about what to test and how to organize a unit test. have you ever wondered then why it's called 'unit' test and not 'class' test? being pragmatic (well, of course we all are pragmatic and agile these days, aren't we?), why not having a more coarse-grained unit than a class under test?

for example, you may have asked yourself more than one time, why not use JUnit for integration tests as well. having used FIT (Framework for Integrated Tests) as a very productive tool for such tests in the past, i wished to have a similar little brother for direct use within JUnit (let's say for developer integration tests).
Especially when it comes to a wide range of combinations of input or setup data for the unit under test, an equivalent of FIT's ColumFixture would be of great value.

So why not write a ColumnTestCase, where we could test our units in a similar way like with a ColumnFixture and specifying input fields and assertion methods directly (so there is no need to write and read html and use Type Adapters as with FIT).

let's say we have a component under test which will calculate a refinancing rate within a loan request for a given credit type. to keep the example simple, the calculated rate should only be dependend on the credit type, the limit and the duration (in months).

a test could look like the following:


public class RefinancingCalculationTest extends ColumnTestCase{

 // the unit under test
 private RefinancingService refinancingService = ...;

 // input
 public CreditType type = null;
 public Limit limit = null;
 public int months = 0;

 // assertion method
 public Rate refinancingRate(){
  return refinancingService.calcRefinancingRateFor(
    new Credit( type, limit, months ) );
 }

 // here comes the test
 public void testCalculationForAnnuityLoan() throws Exception{

  fixture( "type",                       "limit",               "months", "refinancingRate()" );

  testset( CreditType.Annuity,   new Limit( "20000" ),    24,   new Rate( "0.5" ) );
  testset( CreditType.Annuity,   new Limit( "20000" ),    48,   new Rate( "1.0" ) );
  testset( CreditType.Annuity,   new Limit( "80000" ),    24,   new Rate( "3.5" ) );
  // ...
  testset( CreditType.Annuity,   new Limit( "80000" ),    0,     DurationEx.class );
 }
}


this syntax looks like a simple candidate for a kind of ColumnFixture with a very similar behaviour:
refinancingService is our unit under test. it may be constituted in a setUp() method (we still are in an ordinary unit test case).
next comes the input fields, which will hold the specific values for every so called test set. similar to the Fixture class within FIT, this fields are declared public.
the following assertion method normally refers to the input fields and provides the calculated value (and usually delegates the calculation of the value to the unit under test). the calculated value will be compared against the asserted value within each test set. like with FIT, the assertion method has no arguments. all input needed for calculation is defined by the input fields. as you can see, no type conversion of those input fields is necessary, since we can use the right type directly in the test sets (this is different and more simple than with FIT, where you need some Type Adapters to convert the values out of the html document into the right type)

now we have to define the single tests itself. this is done in a single test method (since we use JUnit 1.3.x, the test methods has to start with the prefix test). first of all we define the 'fixture' itself, that is to specify the name of the relevant input fields and assertion method(s). like with FIT, an assertion method is characterized by an opening and closing brace behind the methods name.
all following lines define single test sets. each test set specifies a single, unique combination of input fields along with the asserted value. as you can see, this could be also an asserted exception, maybe for illegal input.

now what's about the implementation of ColumnTestCase? as you will see, this is also quite simple, as all the behaviour is gathered in one single class with not more than 60 lines of code:


**
* Base class for all Test Cases which represent a so called ColumnTestCase.
*
* A ColumnTestCase offers the opportunity - like FITs ColumnFixture -
* to specify a set of input fields and so called assertion methods in a fixture,
* followed by some testsets which specifies a set of concrete input values
* (associated to the specified input fields) and a set of expected values
* (to be compared to the output of the beloning assertion method)
*
* @author Mario Gleichmann
*/
public class ColumnTestCase extends TestCase{

 protected List fields = null;
 protected List assertionMethods = null;

/**
* Sets up the current fixture.
* Determines the specified input fields and assertion methods
* and collects the associated fields and Methods.
*
* @param inOuts
* Specifies the input fields and assertion methods of the current test fixture.
*/
 public void fixture( String...inOuts ){

  fields = new ArrayList();
  assertionMethods = new ArrayList();

  Class clazz = getClass();

  for( String inOut : inOuts ){
   try{

    if( isAssertionMethod( inOut ) ){
     assertionMethods.add(
      clazz.getMethod( inOut.substring( 0, inOut.length() - 2 ) ) );
    }
    else{
     fields.add( clazz.getField( inOut ) );
   }
   }

   catch (Exception e) {
   throw new RuntimeException( e );
   }
  }
 }

/**
* Runs a specific testset within the current fixture
*
* @param testset
* set of current values for the specified input fields and expected
* values for the assertion methods to call.
*/
 public void testset( Object...testset ){
  initFieldsFrom( testset );
  int numberOfFields = fields.size();

  for( int currentAssertionNumber = 0;
       currentAssertionNumber < assertionMethods.size();
       currentAssertionNumber++ ){

   Object expectedValue =
     testset[ numberOfFields + currentAssertionNumber ];

   Object actualValue = null;

   Method assertionMethod =
     assertionMethods.get( currentAssertionNumber );

   try {
    actualValue = assertionMethod.invoke( this );
   }
   catch ( Throwable throwable ) {
    if( isExpectedException( throwable, expectedValue ) ){
     continue;
    }
    throw new RuntimeException(
     "Failure during execution of " +
     assertionMethod.getName() +
     "() - expected: " + expectedValue, throwable );
   }
   assertEquals( assertionMethod.getName() + "() : ",
     expectedValue, actualValue );
  }
 }

/**
* Shows if the given Throwable's cause is the expected
* Result of a call to an assertion method by comparing it
* with the expected value.
*
* @param throwable
* Throwable to test if it is an expected result
*
* @param expectedValue
* The expected value in respect to a call of an assertion method
* Should be of type Class of the expected Throwable (or Superclass)
*
* @return true, if the expected value is of the same type of class or a
* superclass of the Throwable's cause.
* false, otherwise
*/
 private boolean isExpectedException(
   Throwable throwable, Object expectedValue ) {

  return expectedValue instanceof Class &&
    ((Class) expectedValue).isAssignableFrom(
     throwable.getCause().getClass() );
 }

/**
* Initializes the fields with the given values of a testset
*
* @param testset
* Hold the values of the input fields of the current testset
*/
 private void initFieldsFrom( Object... testset ) {
  for( int i=0; i<fields.size(); i++ ){
   try {
    fields.get( i ).set( this, testset[i] );
   }
   catch (Exception e) {
    throw new RuntimeException( e );
   }
  }
 }

/**
* Shows if the given definition (within a fixture specification)
* constitute an assertion method
*/
 private boolean isAssertionMethod( String definition ){
  return definition.endsWith( ")" );
 }
}


as you can see, there's no magic at all, at the core just some reflection and that's it (you will find it under http://sourceforge.net/projects/bricks4j).
now with ColumnTestCase, we have the opportunity to define FIT like tests inside a JUnit test. wheter it's convenient or useful for you depends on the kind of tests you'll run.

all in all it's another little 'tool' that may help to decrease our test idleness. and every tool that ease our efforts and support writing tests is a good one ...

Posted by mario.gleichmann at 22:00:13 | Permanent Link | Comments (2) |

Tuesday, 23. January 2007

FIT - Framework for Integrated Test

a good friend of mine and i recently published a little series of articles about FIT, a simple yet powerful framework for integrated tests at JavaSPEKTRUM, a professional journal for software development in germany.

if you have read the articels you may want to study the full sources, which are mentioned and showed partly within.

i've provided the sources and classes under the following link for download.

feedback is of course always welcome!

enjoy!

Posted by mario.gleichmann at 22:20:48 | Permanent Link | Comments (0) |
1 2