Tuesday, 16 June 2009

Mocking Flex Services

This exercise started as an attempt to be able to test drive the development of an application that used the Cairngorm framework. It turned into implementing a framework that allowed us to mock out the data services and to develop without having the back-end server code available.

This seemed a difficult task until I realised just how dynamic the foundation of Flex really is. The RemoteObject class is a dynamic class. All dynamic classes should extend the Proxy class. Basically, the Proxy class defines the default behaviour for method calls (callProperty) and properties (hasProperty, getProperty, setProperty) that are undefined. By using a Dictionary object, it is easy to redefine these methods and dynamically add functionality to any class.

With my initial experiments, I defined my own RemoteObject subclass that overrode the default callProperty method. This stored the name of the method called and the number of parameters (these come in as an array). This allowed me to write fairly simple tests to ensure that the command / delegate combination of Cairngorm was doing what I expected.

Once I had satisfied myself that the mechanism was working the way that I expected, I added methods to my RemoteObject that allowed me to define the operations and the data that would be returned or possibly to send a fault message back to the caller. In the process of experimenting, we discovered that properties could be added to classes even if the class wasn't declared as dynamic.

The RemoteObject returns an AsyncToken object. It is to this object that the responder object is added. Although the AsyncToken doesn't call the responder, for the purposes of mocking the operation of service calls, it was easier to create a mock AsyncToken and have that call the responder methods as required.

One small trap occurred. I needed to add a delay so that the call to the responder behaved more like a true asynchronous operation. If I didn't, there were some places in our code base that would fail since the response would be received before it was expected. Although the Flash environment is event driven, the Flex code is single threaded. A call to an event handler actually occurs when the event is fired. The solution for mocking purposes is to use a timer event to introduce a delayed event.

When I started this process, I thought it might be more difficult to achieve than it worked out to be. The reason that it proved relatively easy is in part to the dynamic nature of Flex.

No comments: