Thought I’d share this with you..

If you’re using flexUnit and want to test some class or method that dispatches an asyncrhonous event, then this snippet is for you.

I’ve seen this done a few ways, but I recently discovered this neat little feature of flexUnit. If you know this already, then good for you, but if not, let me introduce you to the addAsync method.

Basically, this TestCase method acts as a proxy between you’re addEventListener call and FlexUnit, giving you a teeny bit of extra functionality on the way. The basic use is:

  1. myObject.addEventListener( eventName addAsync( handlerMethod, timeOutInMillisecs ) );

It’s quite straight forward, you provide it with a handler in your TestCase, and if a matching method is not dispatched in the prescribed amount of time, the test fails. Neato.

Here’s an example from one of my current open source projects.. I’ve got a historyManager class, which dispatches a historyMoved event, to any interesting parties, if the moveHistory method is called. It returns at TextEvent with the current history text, for anyone who might like to know.

  1. package test.Controller
  2. {
  3. import flexunit.framework.TestCase;
  4. import flexunit.framework.TestSuite;
  5. import com.FlexTramp.HistoryManager;
  6. import flash.events.TextEvent;
  7. public class HistoryManagerTest extends TestCase {
  8. private var historyManager : HistoryManager;
  9. private var expecectedHistoryString : String;
  10. private var expecectedHistoryIndex : int;
  11. override public function setUp() : void
  12. {
  13. //create history manager with test SO name, to save losing our commands :)
  14. historyManager = new HistoryManager( "test" );
  15. historyManager.clear();
  16. }
  17. override public function tearDown() : void
  18. {
  19. historyManager = null;
  20. }
  21. public function testInitialize() : void
  22. {
  23. assertEquals("pointer should’ve been 0", 0, historyManager.getCurrentIndex() );
  24. }
  25. public function testAddToHistory() : void
  26. {
  27. historyManager.addToHistory( "test1" );
  28. assertEquals("pointer should’ve been 0", 0, historyManager.getCurrentIndex() );
  29. historyManager.addToHistory( "test1" );
  30. assertEquals("pointer should’ve been 0 – last element was duplicate",
  31. 0, historyManager.getCurrentIndex() );
  32. historyManager.addToHistory( "test2" );
  33. assertEquals("pointer should’ve been 1", 1, historyManager.getCurrentIndex() );
  34. }
  35. public function testMoveBack() : void
  36. {
  37. historyManager.addToHistory( "test1" );
  38. historyManager.addToHistory( "test2" );
  39. //the move methods results in a HistoryMoved event being dispatched
  40. historyManager.addEventListener( HistoryManager.HISTORY_MOVED,
  41. addAsync( historyMoved, 2000 ) );
  42. expecectedHistoryString = "test1";
  43. expecectedHistoryIndex = 0;
  44. historyManager.moveHistory(-1);
  45. }
  46. private function historyMoved( event : TextEvent ) : void
  47. {
  48. assertNotNull("event should’ve been returned", event.text);
  49. assertEquals("should’ve returned previous history text",
  50. expecectedHistoryString, event.text);
  51. assertEquals("should’ve been history index " + expecectedHistoryIndex,
  52. expecectedHistoryIndex, historyManager.getCurrentIndex() );
  53. }
  54. }
  55. }

From the snippet, you can see that I can check my event in the historyMoved handler (and any other pertinent properties), but best of all, if the method wasn’t dispatched within 2 seconds, Flexunit will fail. Just to be sure, I checked it by adding a timer to my event dispatcher, and it plays ball..

I’m chuffed – lovely bit of DRY code that I’ve certainly written myself, too many times.. but not any more :-)