Using ServiceCapture to capture data for mock service creation

| No Comments | No TrackBacks

A common design pattern used in Flex applications is leveraging mock delegates in the business layer.  Mock delegates and delegates share the same client/server interface, but the mock versions can be used as stand-ins for the real delegates when a connection to the server cannot be established or perhaps when the server method has not been built or is not integrated yet.

For example, if an application needs to log a user in it might make a call to LoginDelegate::login and pass along the user's credentials.  The server might respond with the detailed user information if the credentials are valid, or it might throw an error or return null of they are not.

Since a login screen is typically the first screen in an application, client-side development is generally dependent on the server's ability to log a user in consistently.  What happens when this isn't the case?  This is where mock delegates shine.  They free client-side developers from server-side dependencies and enable development to proceed even if the server or the remote method is unavailable.

Mate has Mock Services (pdf)  to enable easy mock delegate creation.  With Swiz you build mock delegates that leverage TestUtil.mockResult.  If you google for MockRemoteObject there are other implementations to be found out there, such as this one.

Once mock delegates have been created, populating them with fake data to return usually involves creating some code to generate random data. Something like this...

public function getUserList():ArrayCollection
{
    var users:Array = new Array();
    var user:User;
    
    // Generate 10 fake users
    for ( var i:int = 1; i <= 10; i++ )
    {
        user = new User();
        user.id = i;
        user.firstName = "First " + i;
        user.lastName = "Last" + i;
        // More here... Math.random(), lorem ipsum generation, etc.        

        users.push( user );
    }

    return new ArrayCollection( users );
}

There are more sophisticated tools you can use to generate mock data (this StackOverflow question is probably a good place to start looking), but the general idea of creating fake values and stuffing them into objects still applies.

Fortunately, this process can sometimes be made easier with ServiceCapture (or possibly Charles or another tool, but I'm a ServiceCapture user).

ServiceCapture is a developer tool that captures HTTP traffic on a computer. It enables the introspection of data being sent between the client and server tiers, and includes support for decoding AMF. It also has the ability to save responses received from the server.

That last line is important. With ServiceCapture, it is possible to locally save the response from a server (even AMF responses). These responses can then be used in the mock service layer to accurately simulate real responses in mock scenarios.

Naturally, this technique only works when the remote method is available to capture results from. If client and server development are happening in parallel and the server has not exposed any methods yet, the technique of using a server response as a base for a mock response does not apply. However, when server methods are available to test against, saving responses is both beneficial (since mock data behaves like real data will during development), and time saving (because scripting mock data becomes just a few lines of code).

Here are the steps to take in order to leverage a saved server response in a mock server method:

  1. With ServiceCapture open, make the appropriate call to the remote method from the client application. ServiceCapture will show the request as a line item in it's grid view.
  2. After the result comes back from the server, right-click on the call and select "Save Response" from the context menu.
  3. In the Save dialog, save the response to your local computer. A good practice here is to use the method name and parameters followed by an extension such as ".data" for AMF responses to indicate that the response is binary. For example, if the method is getUserDetails and takes a userId:int parameter, the saved response might be named getUserDetails_13.data.
  4. Place the saved .data file in the appropriate folder location in the project directory, e.g. Project/mock/[projectPackagePath]/services/data (where mock is defined as an additional source folder in the project properties).
  5. In the MockDelegate class, embed the .data file and read in the contents at runtime. Return the contents to the user as the mock result. An example:
    /**
     * This particular example would be used as a mockGenerator for a MockRemoteObject
     * in Mate.
     */
    public class MyServiceMock
    {
    	[Embed( source="data/getUserList.data", mimeType="application/octet-stream" )]
    	private var getUserListData:Class;
    		
    	public function getUserList():ArrayCollection
    	{
    		var response:ByteArrayAsset = ByteArrayAsset( new getUserListData() );
    		response.objectEncoding = ObjectEncoding.AMF3;
    		response.position = 30
    		var ackMessage:AcknowledgeMessage = response.readObject();
    		var collection:ArrayCollection = ArrayCollection( ackMessage.body );
    			
    		// At this point, collection is an ArrayCollection of User instances.  If
    		// we wanted to, we could change some properties here to "mock" more data, but 
    		// just returning the collection is exactly the same as what we would get from
    		// the real service.
    			
    		return collection;
    	}
    }
    

You'll notice that there's some special sauce in the code example above. The server response is created as a ByteArrayAsset, and then the position is moved to position 30 before reading the AcknowledgeMessage instance from it. The actual data being returned is contained in the message's body property.

The position of 30 is not consistent in every scenario and varies based on the server's response, but it usually works. I used a hex editor to determine the location to use to start reading this particular AMF remoting envelope's body response.

A better approach would be to create a small library to pull the response data out automatically. That said, however, this approach can still be a big time saver when it comes to generating mock data. Not only is it faster to create the mock data, but the data itself is a direct copy of real data for the system which gives the application a better feel during development and testing.

In summary, mock delegates enable parallel client/server development, simplify integration, and enable offline development.  By using a tool such as ServiceCapture, you can quickly and easily generate data in your mock services that exactly matches the data returned by the server.

No TrackBacks

TrackBack URL: http://www.darronschall.com/mt/mt-tb.cgi/166

Leave a comment



About this Entry

This page contains a single entry by darron published on September 11, 2009 8:37 AM.

Flash Camp Atlanta 2009 was the previous entry in this blog.

Mate vs. Swiz is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Archives

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.02