Tom Sugden: EventfulTestCase: a FlexUnit extension for testing event dispatching

Main | The Trend Towards Inversion-of-Control Frameworks in Flex »

January 11, 2008

EventfulTestCase: a FlexUnit extension for testing event dispatching

NOTE: The extension described in this post has now been incorporated into FlexUnit 3. The syntax has changed slightly, but the concepts described in this post remain. This feature is not yet available in FlexUnit 4, which is a major update, but work is underway to provide even better support for unit testing the event dispatching behavior of your classes.


The events that a class dispatches form an important part of its contract with clients, yet for one reason or another they are seldom tested. Perhaps this is because event declarations are optional in Flex and specified as metadata, or perhaps it is because the FlexUnit assertions were mostly ported from JUnit and not tailored specifically to Flex. In either case, programming mistakes and design flaws in event logic can have far-reaching consequences, effecting any dependent event listeners and the classes beyond them.

To illustrate the importance of event testing, consider the case of a NuclearReactor class that dispatches temperatureChange events to indicate the effect of adding fuel. Perhaps we also have a MeltdownAlert class that listens for these events in order to raise an alert whenever a boundary temperature is crossed. The melodrama should make it obvious: if the NuclearReactor has a bug that prevents it dispatching events in the expected manner, the MeltdownAlert will never trigger and a catastrophe will unfold.

So it is clearly important to ensure event dispatching logic is correct. To promote the best-practice of unit testing the dispatch of events, I have written a small extension to the FlexUnit TestCase class that makes it easy: EventfulTestCase. This is a new base class for any tests that involve the dispatch of events. It supports both standard Flash events and also Cairngorm events.

The following ActionScript source files accompany this post:

Writing Eventful Test Cases

The process of writing an eventful test case involves first recording the expected events, then performing the action under test, and finally asserting that the expected events occurred. EventfulTestCase defines three kinds of functions to help with this:

  1. expect functions - used to record the events that are expected to occur during the test case.
  2. assert functions - used to assert that the expected events actually occurred.
  3. actual event getters - used to access the actual events that were heard so that more specific assertions can be carried out.

Example 1: testing the dispatch of normal events

Shown below is a simple example which asserts that the temperatureChanges event is dispatched when the addPlutonium() function is called.

public function testAddPlutonium() : void
   // record the expected event
   expectEvent( reactor, TemperatureChangeEvent.TEMPERATURE_CHANGE );
   // perform the action that is being tested
   reactor.addPlutonium( plutonium );
   // assert that the expected events occurred
      "The temperature change event was not dispatched." );

If the expected event is not dispatched, the test case will fail and the developer will be presented with a failure message to assist in debugging. In this case, the message might look like: "The temperature change event was not dispatched. Expected events <temperatureChangedEvent> but heard events <reactorStoppedEvent>". Now the developer knows that the addPlutonium() function contains a logical error which causes the wrong event to be dispatched.

Example 2: testing the dispatch of Cairngorm events

The next example is a little more complex and asserts that two Cairngorm events have occurred. Since Cairngorm events are dispatched through the CairngormEventDispatcher singleton instead of a regular Flex EventDispatcher, the CairngormEventSource adapter class must be used as the event source.

public function testRefreshPlutoniumStocks() : void
   // record the expected events
      CairngormEventSource.instance, // adapter for Cairngorm events
      GetNationalPlutoniumStocksEvent.EVENT_NAME );
   // perform the action that is being tested
   // assert that the expected events occurred
      "The Cairngorm events to fetch local and national " +
      "plutonium stocks were not dispatched." );

Example 3: performing more detailed assertions

The final example builds on the first, demonstrating how to use the actual event getters for performing more detailed assertions.

public function testAddPlutonium() : void
   // record the expected event
   expectEvent( reactor, TemperatureChangeEvent.TEMPERATURE_CHANGE );
   // perform the action that is being tested
   reactor.addPlutonium( plutonium );
   // assert that the expected events occurred
      "The temperature change event was not dispatched." );

   // assert on the details of the actual event
   var temperatureChangeEvent : TemperatureChangeEvent = 
      TemperatureChangeEvent( lastActualEvent );
   var expectedTemperature : Number = 550;
      "The expected temperature change did not occur.",
      temperatureChangeEvent.temperature );

Known Limitations

EventfulTestCase only listens for the expected events and cannot hear unexpected events. The consequence of this is limited detail in the test failure messages. Only the expected events that actually occurred can be reported. The reason for this limitation is that the Flex framework does not enable us to listen to unspecified event types. In other words, we need to register listeners explicitly for each type of event that we want to listen to. One work-around would be to override the dispatchEvent() function of the EventListener framework class, but that would be overly intrusive. This limitation is not severe since the failure messages that can be provided are still reasonably useful.

It should also be noted that EventfulTestCase relies on the fact that most event dispatching takes place synchronously in Flex. When a function dispatches an event, we can be sure that any registered listeners will hear that event synchronously before the function continues and returns. In Flex applications, asynchronicity is typically confined to the I/O operations performed by the Flash Player, and these sit outside the normal realm of unit testing. It is usually possible to mock genuinely asynchronous behaviour, so that the class in question can be tested synchronously. When this is not the case, or for integration testing purposes, a more sophisticated solution is required.


The bugs and design flaws associated with event dispatching often slip the net when unit testing, allowing them to lurk in the deep and strike later. The EventfulTestCase extension helps to prevent this by making it quick and easy to test event dispatching. The process involves three stages: recording expectations, performing actions and asserting that the events occurred. As we attempt to build bigger and better Flex applications, we must test more thoroughly to ensure our success, and this must include testing events.

Posted by tsugden at January 11, 2008 10:28 PM


Great article, looking forward to trying it out

Posted by: Daniel Harfleet at February 6, 2008 12:30 PM


I tried to run the EventfulTestCaseExample, using the Cairngorm 2.2.1 and Cairngorm Enterprise 2.2.1 libraries, and the com.adobe.cairngorm.control.ICairngormEventDispatcher imported in from the example doesn't seem to be available. ( I get 'Type was not found or was not a compile-time constant error' and the ICairngormEventDispatcher is not available in auto-complete under the com.adobe.cairngorm.control ).

Do you use other version than 2.2.1 for your example?

Thank you,

Posted by: Irina at May 21, 2008 1:27 PM

i have the an error with com.adobe.cairngorm.control.ICairngormEventDispatcher
Where does it comes from ? Is this a "special" cairngorn package ?
Thank you

Posted by: Laurent at May 22, 2008 10:31 PM

I found, Cairngorm entreprise must be added to the lib path !!!
Works fine : all tests passed :)
Have a nice day.
Best regards

Posted by: Laurent Roger at May 22, 2008 10:57 PM

I've updated the post to provide a version that is compatible with Cairngorm 2.2.1 and earlier releases. Best, Tom

Posted by: Tom at May 23, 2008 2:57 PM

We would like to use this internally in our company. Could you tell us under what license you are distributing the source code?


Posted by: Rajan Ramasamy at June 23, 2008 9:02 PM


can someone post a full example. I mean the complete test class.

sorry, but i can't imagine how to implement this.

thanks a lot

best regards


Posted by: nilske at December 3, 2008 3:33 PM

Post a comment

Remember Me?

(you may use HTML tags for style)