tutorials flex bouchons
Test classes
When writing unit tests we write a test and then the code that will go into the test. We also need to have the ability to write testable code by isolating a class or a collection of classes. We know that it is quite rare to have classes that are totally independent from the rest of the system. It is for this reason that we put a certain context in place when we want to test certain classes, but the more classes we have to test the more the code gets complicated which shows that we should break certain dependencies.
One of the first steps is the breaking of dependencies with the help of an interface:
This becomes:
This interface allows us to put in place a substitute, which we call a Stopper. We are going to see through the broadcast of class events, the installation of a technique such as Self-hunt or Mock object.
Installation of framework unit tests Flexunit and of the TestRunner component.
Image 1: Addition of the flexunit.swc library
Listing of the basic code to use the TestRunner component:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:it="flexunit.flexui.*" creationComplete="doInit()"> <mx:Script> <![CDATA[ import tests.TestBook; import flexunit.framework.TestSuite; import flexunit.framework.Test; private function doInit():void { testRunner.test = suite(); testRunner.startTest(); } private function suite():TestSuite { var s:TestSuite = new TestSuite(); s.addTestSuite(TestBook); return s; } ]]> </mx:Script> <it:TestRunnerBase width="100%" height="100%" id="testRunner"> </it:TestRunnerBase> </mx:Application>
Let’s now see the techniques.
The Self-hunt technique
It’s a simple technique where the test class plays the role of the Stopper:
// The IBookDao interface package classes { public interface IBookDao { funciton get count():uint; function addContact(contact:*):void; } } // The Book class package classes { import flash.events.EventDispatcher; import classes.events.BookEvent; public class Book extends EventDispatcher { private var dao:IBookDao; public function Book(dao:IBookDao) { this.dao = dao; } public function addContact(contact:*):void { dao.addContact(contact); } } } package tests { import flexunit.framework.TestCase; import classes.Book; import classes.events.BookEvent; import classes.IBookDao; public class TestBook extends TestCase implements IBookDao { private var book:Book; private var numberOfContact:uint; public function get count():uint { return numberOfContact; } override public function setUp():void { book = new Book(this); } public function addContact(contact:*):void { numberOfContact++; } public function testAddTwoListeners():void { book.addContact({}); assertEquals(1,count); } } }
It is a technique that we can quickly find limits to when the class is tested:
- request multiple Stopper instances
- break its dependency, hence the Blocker (the test class)
- and other classes need the same Blocker
To resolve these limits the use of the ‘Mock object’ technique is the most suited.
The Mock object technique
The Mock object consists of writing a class to the play the role of the Blocker:
package tests { import classes.IBookDao; public class MockBookDao implements IBookDao { private var numberOfContact:uint; public function get count():uint { return numberOfContact; } public function addContact(contact:*):void { numberOfContact++; } } } package tests { import flexunit.framework.TestCase; import classes.Book; import classes.events.BookEvent; import classes.IBookDao; public class TestBook extends TestCase { private var book:Book; private var mock:IBookDao; override public function setUp():void { mock = new MockBookDao(); book = new Book(mock); } public function testAddTwoListeners():void { book.addContact({}); assertEquals(1,mock.count); } } }
These two techniques allow you to more easily test a class but it a bit more work. This extra work is in fact a plus when the application becomes more complex and difficult to update.
Over to you now to try to put these techniques to use on your own unit tests.
By ITERATIF - BUGALOTTO Olivier (2007) You can find this tutorial and its comments on my blog
Mediabox Training Centre © 2000 - 2008 All rights reserved.
Adobe Authorized Training Centre. State convention under number 25 14 02167 14.
Mediabox : SARL au capital de 62.000€ - Activity number: 25 14 02167 14 - SIRET : 493 716 468 00027
MEDIABOX, 102 Avenue des Champs Elysées, 75008 PARIS - Tel. +33(0)2.31.91.96.89 - Fax. +33(0)2.72.68.56.42




