Getting Started with junit-objects!

This guide will get you up and running with your first junit-objects test (hopefully)! We will be building and running tests with Ant. The following are requirements for writing and running tests with JO:

  • Apache Ant (I've tested 1.6.5 but earlier versions may work)
  • Version 1.5 of the Java Development Kit (J2SE 5.0)*
  • The junit-objects source. Download from here

* You will need the JDK not just the runtime environment (JRE). Both Sun's Hotspot and BEA's JRockit are acceptable.

Setting Up Dependencies

OK, assuming that went off well, you will now need to add libraries to JO's classpath. These are packaged in a separate release marked dependencies. JO has the following (external) dependencies:

  • Javassist javassist.jar - The bytecode instrumentation library
  • OGNL ognl-2.6.7.jar - The Object Graph Navigation Language (2.6.7 or later)
  • Xerces xercesImpl.jar - The Apache Xerces XML parser (should be included with JDK 5)
  • Junit junit.jar - For running unit tests on the JO codebase itself (oh irony!)

Note: Xerces is not provided (as it ships with JDK 5) and Junit is not provided as it is not needed to build and run junit-objects.

Download and/or copy these jars over to a unique directory (let us call it jo-lib for argument's sake). Now, extract your junit-objects-src..jar release file to a working directory. Edit the property file for ant and set it to match your environment and liking.

ant.properties

#JO build dirs
src=.
build=build

#put your own lib path here
lib=/dev/java/lib/jo-lib

The only thing you really need to set is lib. Note that all JAR files under the specified directory and ALL its sub-directories will be included in the classpath.

Building And Running the Sample Target

Now, from the new JO working directory run Ant on the "sample" target. You should see something like this:

$ ant sample
Buildfile: build.xml

clean:

init:
    [mkdir] Created dir: D:\eclipse\workspace\junit-objects\build

build:
    [javac] Compiling 51 source files to D:\eclipse\workspace\junit-objects\build
     [copy] Copying 1 file to D:\eclipse\workspace\junit-objects\build

sample:
     [java] @Metaphor: testToggleBool
     [java] chain sampleStateChain2; state assertion fired: sample3
     [java]     assert property ognl:(boolField as true)  [OK]
     [java] chain sampleStateChain; state assertion fired: sample
     [java]     assert property object:(boolField as not-null)  [OK]
     [java]     assert property object:(boolField as castable:java.lang.Object)  [OK]
     [java]     assert property object:(boolField as instanceof:java.lang.Boolean)  [OK]
     [java]     assert property boolean:(boolField as false)  [OK]
     [java]     assert property ognl:(boolField as #this == false)  [OK]
     [java]     assert property ognl:(boolField as !#this)  [OK]
     [java]     assert property ognl:(boolField as true)  [OK]

BUILD SUCCESSFUL
Total time: 13 seconds


A Brief Explanation Of The Output

  • Here's how to read a property assertion:
    assert property [protocol]:([property-name] as [assert-expression]) [OK]
  • Two state chains were asserted in this metaphor, namely sampleStateChain2 and sampleStateChain. Each of them contained exactly 1 state assertion sample3 and sample respectively.
  • Both chains were part of the same metaphor, namely testToggleBool of the SampleObjectTest which looks like this:

    package test.junitobjects;
    
    import com.wideplay.junitobjects.*;
    
    @Objects("com/wideplay/junitobjects/unittests/test.objects.xml")
    public class SampleObjectTest extends ObjectTestCase {
    
        /** main simply runs the test with JO */
        public static void main(String a[]) {
            Tester tester = ObjectsBackplane.getObjectTester(SampleObjectTest.class);
    
            tester.run();
        }
    
        /** this is our metaphor */
        @Metaphor
        public final void testToggleBool() {
            SampleObject so = new SampleObject();
    
            //calling this method triggers the state-chain automatically
            so.toggleBoolField();
        }
    }
    

  • Notice that all 7 assertions for sample are on the same property boolField, but also that they occur in the same sequence as specified in the state-descriptor:

    <object-state name="sample">
    	<boolField>object:not-null</boolField>
    	<boolField>object:castable:java.lang.Object</boolField>
    	<boolField>object:instanceof:java.lang.Boolean</boolField>
    	<boolField>boolean:false</boolField>
    	<boolField>ognl:#this == false</boolField>
    	<boolField>ognl:!#this</boolField>
    	<boolField>ognl:true</boolField>
    </object-state>

  • It is important to note that the assertion boolean:true is different from ognl:true. The former asserts the property value to be true, whereas the latter simply asserts true (meaning it will never fail). To assert that a property is true via ognl you would write the expression as
    ognl: #this == true or simply, ognl: #this.
  • Each state-chain was triggered when toggleBoolField() was called in the metaphor. This is what toggleBoolField() and SampleObject look like:

    package test.junitobjects;
    
    /** This is our class under test */
    public class SampleObject {
        public boolean boolField = true;
    
        /** This method affects boolField, but is watched
         *  by JO and used as a state-chain trigger
         */
        public void toggleBoolField() {
            boolField = !boolField;     //toggle true/false
        }
    }

  • The triggers and test-sequences are set using a state-chain descriptor, as follows:

    <state-chain name="sampleStateChain" metaphor="testToggleBool"
    	class="test.junitobjects.SampleObject">
    
    	<trigger name="sampleStateChainTrigger" method="toggleBoolField"
    		class="test.junitobjects.SampleObject"/>
    
    	//binding to state-descriptor "sample"
    	<state refid="sample"/>
    </state-chain>

    See the Writing your first test guide for a proper introduction to state-chains and assertion testing

GetJava Download Button
SourceForge.net Logo
Support This Project