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

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:
userMessage parameter indicates an optional message to be prepended for a failure message.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 && userMessage.length > 0) { userMessage += ' - '; } throw new AssertionFailedError(userMessage + 'Expected: <' + expected + '> but was: <' + actual + '>'); } } } }
Related posts:
Topics: actionscript, Flex, flexunit, PureMVC, Testing