3.3. SIN Expressions

Simple Invocation Notation (SIN) Expressions are used within Sureassert to create and invoke methods on Objects in the testing context. All Exemplar property values are given as Strings. Sureassert reads the values as SIN Expressions and creates or invokes methods on Objects accordingly.

3.3.1. SIN Types

The simplest form of SIN Expression is a SIN Type. SIN Types are used to quickly create typical objects and populate them with data.

There are 2 types of SIN Types: those that require prefixing to indicate the type of the Object being created, and those that don’t (where the type is determined automatically based on the value.

3.3.1.1. Basic SIN Types

Basic SIN Types are those that do not require a prefix, where the type of the Object to be created can be determined simply from the value itself. These are:

Java Object Basic SIN Type Prefixed SIN Type
new String(“str”) ‘str’ s:str
new Boolean(true) true b:true
new Boolean(false) false b:false
new Integer(5) 5 i:5
new Double(5.0) 5.0 d:5.0
new Float(5.0) 5.0f float:5.0
new Long(5) 5l lg:1
new Short(5) 5s short:5

3.3.1.2. Built-in Prefixed SIN Types

Built-in Prefixed SIN Types require a prefix to determine which type of Object is to be created:

Type Example SIN Type
Object array new String[] {“x”,”y”,”z”} a:’x’,’y’,’z’
Primitive array new int[] {1,2,3} pa:1,2,3

Empty primitive array new double[] {} ea:[d:]

List List list = new ArrayList();

list.add(1);

list.add(2);

list.add(3);

l:1,2,3
Map Map map = new HashMap();

map.put(“key1”,1);

map.put(“key2”,2);

map.put(“key3”,3);

m:’key1’=1,’key2’=2,’key3’=3
Set Set set = new HashSet();

set.add(1);

set.add(2);

set.add(3);

s:1,2,3
File File file = new File(“resources/test.xml”); f:resources/test.xml

(relative from project root)

String (read from File) org.apache.commons.io.FileUtils.readFileToString(file, “UTF-8”); sf:resources/test.xml

(relative from project root)

3.3.1.3. Defining your own SIN Types

You can create or retrieve test objects using SIN Expressions, potentially calling out to a method to retrieve and populate your object.

However where you frequently need to create or retrieve a given type of object, it can be simpler and cleaner to define your own SIN Type.

You do this by creating a public static method anywhere in your project that returns any kind of Object and takes any number of parameters, and annotating it with @SINType:

@SINType(prefix="ab")
public static Object getNamedAppBean(String beanName, int contextID) {

    Object bean = /*retrieve the bean with the given name from aunit test DI context*/
    return bean;
}

Then in an Exemplar:

@Exemplar(args="ab:'flightAB123',1")
public void cancelFlight(Flight flight) {

    int flightID = flight.getID();
    ...
}

Often however, you will use objects returned by other Exemplars defined in your projects. See the Named Instances section for more details.

3.3.2. Java Primitives and Wrapping

Sureassert depends upon auto-boxing/unboxing and therefore requires Java 5 and above. Primitives and wrapped types (e.g. int values and Integer objects) will be automatically converted to the required value/type when passing arguments and asserting results.

One exception to this is primitive arrays, which are created using the pa: SIN Type (primitive array) rather than a: (object array). For example, to create an array of double values use pa:1.5,2.5. To create an array of Double objects use a:1.5,2.5.

3.3.3. Nested SIN Types

When placing prefixed SIN Types within expressions or nested within other SIN Types, you must use square brackets. Square brackets are not required to nest non-prefixed SIN Types. For example to create a map whose key is a String and values are Lists of Integers:

m:'key1'=[l:1,2],'key2'=[l:1,2,4],'key3'=[l:1,2,4,8]

3.3.4. Basic SIN Expressions

The most simple expression is to just use a SIN Type value:

instance

Instance may be a SIN Type, a named instance or class (see later sections), or another SIN Expression. Basically anything that returns an object or primitive.

You can get the value of any field regardless of its access modifier (public, private, protected):

instance.field

A basic SIN Expression is very similar to a Java method invocation or field getter:

instance.field
instance.method(arg1, argN)

Just like the instance, method arguments can be anything that returns an object or primitive, including named instances or other (bracketed) SIN Expressions.

Similarly methods can be invoked on the returned object:

instance.method(arg1, argN).method2(arg1,argN)

For example:

@Exemplar(args="m:'key1'=[l:1,2,3],'key2'=[l:4,5,6]", expect="$arg1.get('key2').get(2).equals(7)")
public static void incrementAll(Map<String, List<Integer>> map) {

    for (List<Integer> intList : map.values()) {
        for (int i = 0; i < intList.size(); i++) {
            intList.set(i, intList.get(i) + 1);
        }
    }
}

$arg1 is a special named instance that returns the first argument passed into the method. See the Named Instances section for details.

Expressions can be used within other expressions but unlike Java the nested expression must be bracketed:

instance.method(arg1, (instance2.method2()))

3.3.5. Named classes

You can reference java.lang classes and any class defined within your project source code by its simple (unqualified) name. All other classes (e.g. library classes) must be referred to by their fully-qualified name. Note Sureassert uses “/” as the package separator rather than “.”:

SIN Expression to invoke static method1 on MyProjectClass:

MyProjectClass.method1()

SIN Expression to invoke static libMethod on SomeLibraryClass:

com/someproject/SomeLibraryClass.libMethod()

You can create new instances of a class in the normal way:

new MyProjectClass(arg1, arg2)

As part of the constructor call you can also set values for the new object’s fields:

new MyProjectClass(arg1, arg2) {field1=val1, field2=val2}

val1/val2 can be any expression that returns an Object or primitive compatible with the type of field being set.

3.3.6. Accessing Private and Protected Fields and Methods

In a testing context, access modifiers can get in the way: often within your tests you need to be able to assert the correctness of private state of the object under test. It should not be necessary to compromise your design and/or break encapsulation within your production code in order to facilitate this.

With Sureassert you can use SIN Expressions to get the values of private fields and invoke private methods on your objects, as though they were public.

3.3.7. SIN Operators

Java operators are handled as built-in method calls by Sureassert. All common java operators have equivalent methods or method symbols that replace them within SIN Expressions. In addition, Sureassert includes some additional convenience methods:

Java Operator / method Java Example SIN Example
= obj.field1 = x

obj.field2 = y

obj{field1=x,field2=y}
== a == b ==(a,b)
n/a (a==null && b==null) || (a!=null && a.equals(b)) =(a,b)
!= a != b !=(a,b)
instanceof a instanceof b isa(a,b)
> a > b >(a,b)
< a < b <(a,b)
>= a >= b >=(a,b)
<= a <= b <=(a,b)
! !a !(a)
&& a && b &&(a,b)
|| a || b ||(a,b)
+ 1 + 2

“str1” + “str2”

+(1,2)

+(‘str1′,’str2′)

[] fooArray[n] #(fooArray,n)
Arrays.deepEquals Arrays.deepEquals(array1, array2) #=(array1,array2)


Previous Page   |   Next Page   |   Table of Contents

Comments are closed.