Introduction

Expando object can make dynamic object, properties and methods if you like. This can be used for stubbing an object to be used for testing.

For example if have the following:

Code 1 - processor function that requires the SSampleStructure structure

//Structure works with objects with similar features but no common inheritance and interface declarations
structure SSampleStructure {
  function someAction() : int
}

function processor(sample : SSampleStructure) : int {
  return sample.someAction() + 10
}

The SSampleStructure structure will be compliant to all the classes that has someAction function that returns an int. And the actual compliant implementation of the structure is the following:

Code 2 - Actual implementation that is compatible with SSampleStructure

class SampleCodeWithStaticMethods {

  private construct() {}

  function someAction() : int {
    return (Math.round(Math.random()*100) as int) + 100
  }
}

We can notice that in Code 2, we cannot have a consistent output for someAction method since it is return arbitrary values. And what the processor function does is just add 10 on it.

What we can do here is to create an Expando object that will also comply with SSampleStructure structure like the following:

Code 3 - Using Expando class

uses gw.lang.reflect.Expando
  
    // By declaring the Dynamic type for the variable or function argument, you can
// programmatically access any property or method without requiring compile-time confirmation of its existence.
var testObj : Dynamic =

// An expando object is an object whose properties, and potentially methods, are created dynamically on assignment.
    new Expando()

// We can attached function using the block syntax as below.  
testObj.someAction = \ -> 25

Since the testObj of Code 3, also has someAction function that returns an int. This is compliant with SSampleStructure structure. So we can safely run the following test of logic without any problem:

Code 4 - Actual test

function testProcessor() {
  print("Is35: " + (processor(testObj)==35))
}

testProcessor()

As we can see from Code 4, we are using testObj to test the processor method.