Notification Testing with PureMVC and FlexUnit

flex-puremvc

One of the nice extensions available for FlexUnit is the ability to easily unit test event behavior using EventfulTestCase.

This library has support for testing Cairngorm, but unfortunately support is lacking for PureMVC. I searched for existing solutions which added PureMVC notification support, but was not satisfied with their APIs. Luckily, it was not difficult to write some code to support PureMVC which mirrored the API of EventfulTestCase.

The code at the end of this post is a start at duplicating the EventfulTestCase behavior. It doesn't have all the functionality, but it is enough for simple tests.

Here are the methods which are made available:

  • expectNotification(notificationName:String) Sets up the expectation that a notification is sent with the passed name. Can be called multiple times to set the expectation for multiple notifications.
  • assertExpectedNotificationsOccurred(userMessage='') Asserts that all expected notifications were sent. The userMessage parameter indicates an optional message to be prepended for a failure message.
  • lastActualNotification Property which represents the last notification which was sent (the last actual notification).

The following is an example of the kind of test you can write:

 
public class ChuckProxyTest extends PureMvcTestCase
{
    private var chuck:ChuckProxy = new ChuckProxy();
 
    public function testShouldSendFlashNotificationWhenSeeingTerrorist():void
    {
        var terrorist:Terrorist = new Terrorist();
        expectNotification(ApplicationFacade.FLASHED);
 
        chuck.lookAt(terrorist);
 
        // asserts FLASHED notification was sent
        assertExpectedNotificationsOccurred();
        // asserts notification body was the terrorist
        assertEquals(terrorist, lastActualNotification.getBody());
    }
}
 

Finally, here is the code. Notice the package; you will need to add it to test/org/puremvc/as3/test.

 
package org.puremvc.as3.test
{
    import flexunit.framework.AssertionFailedError;
    import flexunit.framework.TestCase;
 
    import org.puremvc.as3.core.View;
    import org.puremvc.as3.interfaces.INotification;
    import org.puremvc.as3.patterns.observer.Observer;
 
    public class PureMvcTestCase extends TestCase
    {
 
        private var expectedNotificationNames:Array = [];
        private var actualNotifications:Array = [];
 
        public function PureMvcTestCase(methodName:String=null)
        {
            super(methodName);
        }
 
        protected function expectNotification(notificationName:String):void
        {
            assertNotNull('No instance exists for View.getInstance()', View.getInstance());
            expectedNotificationNames.push(notificationName);
 
            View.getInstance().registerObserver(notificationName, new Observer(
                function(notification:INotification):void {
                    actualNotifications.push(notification);
                },
                null));
        }
 
        protected function get lastActualNotification():INotification
        {
            if (actualNotifications.length == 0) {
                return null;
            }
            return actualNotifications[actualNotifications.length - 1];
        }
 
        protected function assertExpectedNotificationsOccurred(userMessage='The expected notifications were not sent'):void
        {
            var actualNotificationNames:Array = [];
 
            for(var notificationIndex:int = 0; notificationIndex < actualNotifications.length; notificationIndex++) {
                actualNotificationNames.push(actualNotifications[notificationIndex].getName());
            }
 
            assertArraysEqual(expectedNotificationNames, actualNotificationNames, userMessage);
        }
 
        protected function assertArraysEqual(expected:Array, actual:Array, userMessage:String = null):void
        {
            var equal:Boolean = (expected.length == actual.length);
 
            if (equal) {
                for(var i:int = 0; i < actualNotifications.length; i++) {
                    if (expected[i] != actual[i]) {
                        equal = false;
                        break;
                    }
                }
            }
 
            if (!equal) {
                if (userMessage &amp;&amp; userMessage.length > 0) {
                    userMessage += ' - ';
                }
 
                throw new AssertionFailedError(userMessage + 'Expected: <' + expected + '> but was: <' + actual + '>');
            }
        }
    }
}
 

Related posts:

  1. Using Flex Code Generator (FCG) with Flex & PureMVC
  2. Flare on PureMVC in Flex example
  3. Learning PureMVC the Hard Way (is there any other way?)
  4. WinForms Development Made Simple with PureMVC
  5. Griffon and a PureMVC Plugin: Some Initial Thoughts

Leave a comment

Powered by WP Hashcash

Launch: Pathfinder Newsletter

    Get a monthly update on best practices for delivering successful software.

    Subscribe via email


    Subscribe via RSS      RSS icon

Topics

Search

WordPress

Comments about this site: info@pathf.com